Syntax Highlighter – in 20 minutes…

Ok I cheated slightly, I had the basic sub routine at the bottom of this code already working. The dictionary and lists idea came just now and I’ve implemented it in 20 minutes. This is quick, dirty and Winforms.

Why? I want it for my custom code generator – to be blogged soon.


Module SyntaxHighLighter
ReadOnly DarkBlue As List(Of String) = New List(Of String)(New String() {"public", "private", "sub", "byval", "byref", "integer", "Friend", "friend",
"Shared", "shared",
"long", "string", "object", "handles", "for", "to", "as",
"if", "in", "then", "end", "next", "loop", "dim",
"redim", "new", "of", "and", "function", "class", "me", "#Region", "RaiseEvent", "Return",
"While", "With", "Get", "Set", "Property", "#End Region"})

ReadOnly Grey As List(Of String) = New List(Of String)(New String() {"<#@", "#>"})
ReadOnly Maroon As List(Of String) = New List(Of String)(New String() {"import", "assembly", "output"})
ReadOnly Red As List(Of String) = New List(Of String)(New String() {" extension", "namespace"})

Dim LightBlue As List(Of String) = New List(Of String)(New String() {"implements", "List(Of"})

Public Sub SyntaxHighLight(richText As RichTextBox)
richText.Font = New Font("Arial", 10, FontStyle.Regular)
Dim colourDict As New Dictionary(Of List(Of String), Color) From {{Grey, Color.Gray},
{Red, Color.Red},
{Maroon, Color.Maroon},
{DarkBlue, Color.DarkBlue},
{LightBlue, Color.LightBlue}}

richText.SelectAll()
richText.SelectionColor = Color.Black

For Each item In colourDict
SyntaxHighLight(richText, item.Key, item.Value, FontStyle.Regular)
Next

End Sub

Public Sub SyntaxHighlight(richText As RichTextBox, Words As List(Of String), color As Color, style As FontStyle)

Dim FoundPos As Integer = 0
For Each w As String In Words
While FoundPos <> -1 And FoundPos < richText.TextLength FoundPos = richText.Find(w, FoundPos, RichTextBoxFinds.WholeWord) If FoundPos > -1 Then
richText.Select(FoundPos, w.Length)
richText.SelectionColor = color

richText.SelectionFont = New Font("Arial", 10, style)
richText.SelectionLength = 0
FoundPos += w.Length
End If
End While
FoundPos = 0
Next
End Sub
End Module

Very simple List Comprehension

This is another rushed post making me slightly late for work, but I thought of it in the shower and decided to try and teach to my brother. So forgive the lack of testing of my syntax!

You may see something like (1..10, x > 10, x = x*x)

This is functional programming idea called a list comprehension that makes it easy to get a list and do stuff to it.

Instead of typing

For each person in a list(of person)
If person.hashairRed and PersonIsFemale then
GiveBadge(Person)
end if
Next

This is a list comprehension and my syntax is generic.

Here is how to understand the idea:

1..10 could be any range of values. Say it is a group of ten people.

Then you can decide which people you wish to operate on. So X >10 could be replaced for X is a person with red hair who is a woman .

Then you decide what to do with those people. so X*X so instead I say give each one a badge. This is a function you wish to apply to the individual.

So really I’m saying in a room there are 10 people all mixed and I want to give red haired woman a badge.

(List (of PeopleInARoom), Person.HasHair(Red) =True And IsFemale, GiveBadgeToPerson(Person))

This is a very general way to understand the idea.

Is this a monad?

My first shot at a monad.

Right now my family are due to knock at the front door, yet whilst getting ready I was mulling over monads. I’m now rushing this post to my blog to make sure I have it down. I was explaining monads to myself in the shower and examining them in the light of how would I make LINQ work? I realised that LINQ must be built of continuations, passing values and functions into extension functions. Can I prove that?

This is no definitive answer, just something I created to explain it to myself. The recursion in the extension is completely unnecessary, I was simply proving I could pass in a different function if I wished.

I’m not going to try and explain monads as many others, better than I have done so – plus if the code below is mostly correct, it is probably self explanatory. Make a function that takes a both a value and another function to operate on. I have a feeling there is a bit more to it, answers on a postcard anyone?

Below is the simplest version I could come up with in ten minutes.

Module Monad

Sub Main()
Dim testList As New List( Of String) From { "One" , "Three" , "two" , "1" , "Nine" }
Dim upperCase = Function(x As String) x.ToString.ToUpper
testList.Continuation(upperCase)
End Sub

< Extension()>
Function Continuation(stringList As List( Of String), f As Func( Of String, String ))

For Each item In StringList
Console.WriteLine(f(item))
Next
Console.ReadLine()

Dim test = Function(x) x.ToString.ToLower()
Return StringList.Continuation(test)
End Function

End Module