Continuation
vb
#Region "DRAW LINES"
Private Sub DrawLine(ByRef g As Graphics, ByRef penWIDTH As Single, ByRef pencolor As Color, ByRef X As Integer, ByRef Y As Integer, ByRef Ox As Integer, ByRef Oy As Integer)
' Draw an offset line on the current graphics surface.
Using usethispen As New Pen(pencolor, penWIDTH)
g.DrawLine(usethispen, X, Y, X + Ox, Y + Oy)
End Using
End Sub
Private Sub DrawLine2(ByRef g As Graphics, ByRef penWIDTH As Single, ByRef pencolor As Color, ByRef X As Integer, ByRef Y As Integer, ByRef Ox As Integer, ByRef Oy As Integer)
' Draw a line a line connection (X,Y) to (Ox,Oy)
Using usethispen As New Pen(pencolor, penWIDTH)
g.DrawLine(usethispen, X, Y, Ox, Oy)
End Using
End Sub
#End Region
#Region "THE COMMANDS"
#Region "COMMAND: PRINT"
Private Function Command_Print(ByRef state As ScriptState, ByRef cl() As String) As Boolean
' Command: PRINT <Text>
Dim FormatString As String = "PRINT"
Dim LineString As String = "Line: " & state.LineNumber.ToString & vbCrLf
' How many fields does the command have?
Select Case cl.Length
Case 2
COutput.Text &= cl(1) & vbNewLine
Case Else
ErrorMessage("Unknown PRINT format" + vbNewLine)
Return False
End Select
Return True
End Function
#End Region
#Region "STORED PROCEDURE COMMAND"
#Region "MAKESHAPE"
Private Function Command_MakeShape(ByRef state As ScriptState, ByRef cl() As String) As Boolean
' Command: MAKESHAPE <Name>
' Rules;-
' 1. No nested MAKESHAPEs
' 2. Name must be unique
Dim FormatString As String = "MAKESHAPE"
Dim LineString As String = "Line: " & state.LineNumber.ToString & vbCrLf
' How many fields does the command have?
Select Case cl.Length
Case 2
' It has 2 fields
' 0) MAKESHAPE
' 1) <Name>
'
' What is the current state of MakingShape
Select Case state.MakingShape
Case False
' Currently not making a shape.
' So is the name unique?
If state.ContainsShapeName(cl(1)) = True Then
' Breach of Rule 2
ErrorMessage(LineString & "Possible Cause;-" & vbNewLine & "1. The name is already being used.")
Return False
Else
' Yes it unique.
' Set the makingShape state to True
state.MakingShape = True
' Create a newShape
Dim newShape As New LogoShape
' Give it ites name.
newShape.ShapeName = cl(1)
' Add it the collection of other shapes.
state.myShapes.Add(newShape)
' Increment the shape Number
state.ShapeNumber += 1
End If
Case True
' Breach of rule 1
ErrorMessage(LineString & "Possible Causes;-" & vbNewLine & "1. Missing ENDSHAPE" & vbNewLine & "2. Nested MAKESHAPE are not allowed")
Return False
End Select
Case Else
Dim MessageText As String = LineString _
& "Error: Unknown Command" & vbNewLine _
& "Usage: MAKESHAPE <Name>" & vbNewLine _
& "Rules;-" & vbNewLine _
& "1. No Nesting" & vbNewLine _
& "2. <Name> must be unique"
ErrorMessage(MessageText)
Return False
End Select
Return True
End Function
#End Region
#Region "COMMAND: ENDSHAPE"
Private Function Command_EndShape(ByRef state As ScriptState, ByRef cl() As String) As Boolean
' Command: ENDSHAPE
' Rules;-
' 1. Must have a matching MAKESHAPE
Dim LineString As String = "Line: " & state.LineNumber.ToString & vbCrLf
Select Case cl.Length
Case 1
' Is the engine is making a shape?
Select Case state.MakingShape
Case True
' Yes, so set the MakingShape flag to true
state.MakingShape = False
Case False
' Unrecognised Command
ErrorMessage(LineString & "Missing MAKESHAPE")
Return False
End Select
Case Else
' Unrecognised Command
Dim MessageText As String = LineString _
& "Error: Unknown Command" & vbNewLine _
& "Usage: ENDSHAPE" & vbNewLine _
& "Rules;-" & vbNewLine _
& "1. Must have a matching MAKESHAPE"
ErrorMessage(MessageText)
Return False
End Select
Return True
End Function
#End Region
#Region "COMMAND: DRAWSHAPE"
Private Function Command_DrawShape(ByRef state As ScriptState, ByRef cl() As String, ByRef g As Graphics) As Boolean
' Command: DRAWSHAPE <Name>
' Rules;-
' 1. <Name> must have been made before it drawn.
' 2. <Name> can't the same as the MAKESHAPE it is it.
' 3. <Name> mustn't trigger a recursion.
Dim FormatString As String = "DRAWSHAPE"
Dim LineString As String = "Line: " & state.LineNumber.ToString & vbCrLf
Select Case cl.Length
Case 2
' Is Rule 1 breached?
If state.ContainsShapeName(cl(1)) = False Then
' Rule 1 broken.
ErrorMessage(LineString & "This shape name isn't known to me.")
Return False
Else
' Is Rule 2 broken?
If mState.myShapes(mState.ShapeNumber).ShapeName = cl(1) And mState.MakingShape Then
' Yes
ErrorMessage(LineString & "I can't draw the shape whilst still making it.")
Return False
End If
' Is Rule 3 broken.
If state.ShapeStack.Contains(cl(1)) = True Then
ErrorMessage(LineString & "Recursive drawing of shapes is not allowed")
Return False
Else
' No Rules Broken, so push shape name being called onto the shaoe Stack
state.ShapeStack.Push(cl(1))
Dim snumber As Integer = state.IndexOfShapeName(cl(1))
' If the excution of the store shape, causes an error return false
If ExcuteScript(state.myShapes(snumber).ShapeData, g, COutput, True) = False Then Return False
' excuted ok the pop the shape name off the shape stack
If state.ShapeStack.Count > 0 Then state.ShapeStack.Pop()
End If
End If
Case Else
' Unrecognised Command
Dim MessageText As String = LineString _
& "Error: Unknown Command" & vbNewLine _
& "Usage: DRAWSHAPE <ShapeName>" & vbNewLine _
& "Rules;-" & vbNewLine _
& "1. The Shape <ShapeName> must have been made before it can be drawn." & vbNewLine _
& "2. <Shape> can not be the same as the MAKESHAPE it is contained within." & vbNewLine _
& "3. Recursive calling of shapes is not allowed."
ErrorMessage(MessageText)
Return False
End Select
Return True
End Function
#End Region
#End Region
#Region "COMMAND: TURN"
Private Function Command_Turn(ByRef state As ScriptState, ByRef cl() As String) As Boolean
Dim LineString As String = "Line: " & state.LineNumber.ToString & vbCrLf
Select Case cl.Length
Case 3
Select Case cl(1)
Case "FACE"
Dim turnangle As Single = 0
If IsNumeric(cl(2)) = True Then
If mState.MakingShape = False Then
turnangle = Val(cl(2))
mState.Angle = turnangle
mState.Angle = mState.Angle Mod 360
End If
Else
Select Case cl(2)
Case "NORTH" : mState.Angle = 0
Case "EAST" : mState.Angle = 90
Case "SOUTH" : mState.Angle = 180
Case "WEST" : mState.Angle = 270
Case Else
ErrorMessage("Sorry I don't know that direction.")
Return False
End Select
End If
Case "LEFT"
Dim turnangle As Single = 0
If IsNumeric(cl(2)) = False Then
' Unrecognised Command
ErrorMessage(LineString & "Unrecognised Command")
Return False
Else
If mState.MakingShape = False Then
turnangle = Val(cl(2))
mState.Angle += turnangle
mState.Angle = mState.Angle Mod 360
End If
End If
Case "RIGHT"
Dim turnangle As Single = 0
If IsNumeric(cl(2)) = False Then
' Unrecognised Command
ErrorMessage(LineString & "Unrecognised Command")
Return False
Else
If mState.MakingShape = False Then
turnangle = Val(cl(2))
mState.Angle -= turnangle
mState.Angle = mState.Angle Mod 360
End If
End If
Case Else
' Unrecognised Command
ErrorMessage(LineString & "Unrecognised Command")
Return False
End Select
Case Else
' Unrecognised Command
ErrorMessage(LineString & "Unrecognised Command")
Return False
End Select
Return True
End Function
#End Region
#Region "COMMAND: ROTATE"
Private Function Command_Rotate(ByRef state As ScriptState, ByRef CL() As String) As Boolean
Dim FormatString As String = "ROTATE"
Dim LineString As String = "Line: " & state.LineNumber.ToString & vbCrLf
Select Case CL.Length
Case 2
If IsNumeric(CL(1)) = False Then
' Unrecognised Command
ErrorMessage(LineString & "Unrecognised Command")
Return False
Else
If mState.MakingShape = False Then
Dim TurnAngle As Double = Val(CL(1))
state.Angle = (state.Angle - TurnAngle) Mod 360
End If
End If
Case Else
' Unrecognised Command
ErrorMessage(LineString & "Unrecognised Command")
Return False
End Select
Return True
End Function
#End Region
#Region "COMMAND: PEN"
Private Function Command_Pen(ByRef state As ScriptState, ByRef commandline() As String) As Boolean
Dim FormatString As String = "PEN"
Dim LineString As String = "Line: " & state.LineNumber.ToString & vbCrLf
' How many parameters does the command have, (this includes the command itself)?
Select Case commandline.Length
Case 2
Select Case commandline(1)
Case "UP" : state.PenDown = False
Case "DOWN" : state.PenDown = True
Case Else
' Unrecognised Command
ErrorMessage(LineString & "Unrecognised Command")
Return False
End Select
Case 3
Select Case commandline(1)
Case "COLOR"
Select Case commandline(2)
Case "RED" : state.Color = Color.Red
Case "BLACK" : state.Color = Color.Black
Case "BLUE" : state.Color = Color.Blue
Case "GREEN" : state.Color = Color.Green
Case Else
' Unrecognised Command
ErrorMessage(LineString & commandline(2) & " is not a recognised color.")
Return False
End Select
Case "WIDTH"
If IsNumeric(commandline(2)) Then
Dim SetWidth As Double = Val(commandline(2))
If SetWidth > 0 Then
state.Width = SetWidth
Else
ErrorMessage(LineString & "Pen Width must be greater the Zero.")
End If
Else
Select Case commandline(2)
Case "NORMAL" : state.Width = 1
Case "BIG" : state.Width = 3
Case "THIN" : state.Width = 0.5
Case Else
' Unrecognised Command
ErrorMessage(LineString & "Unrecognised Command")
Return False
End Select
End If
Case Else
' Unrecognised Command
ErrorMessage(LineString & "Unrecognised Command")
Return False
End Select
Case 5
Select Case commandline(1)
Case "COLOR"
If IsNumeric(commandline(2)) And IsNumeric(commandline(3)) And IsNumeric(commandline(4)) Then
Dim red As Integer = Val(commandline(2))
Dim green As Integer = Val(commandline(3))
Dim blue As Integer = Val(commandline(4))
If Not (red >= 0 And red <= 255) Then
' Unrecognised Command
ErrorMessage(LineString & "Red Values must be within the range 0 to 255 inclusive.")
Return False
End If
If Not (green >= 0 And green <= 255) Then
' Unrecognised Command
ErrorMessage(LineString & "Green Values must be within the range 0 to 255 inclusive.")
Return False
End If
If Not (blue >= 0 And blue <= 255) Then
' Unrecognised Command
ErrorMessage(LineString & "Blue Values must be within the range 0 to 255 inclusive.")
Return False
End If
state.Color = System.Drawing.Color.FromArgb(red, green, blue)
Else
' Unrecognised Command
ErrorMessage(LineString & "One of the color values is not a number.")
Return False
End If
Case Else
' Unrecognised Command
ErrorMessage(LineString & "Unrecognised Command")
Return False
End Select
Case Else
' Unrecognised Command
ErrorMessage(LineString & "Unrecognised Command")
Return False
End Select
Return True
End Function
#End Region
#Region "COMMAND: MOVE"
Private Function Command_Move(ByRef state As ScriptState, ByRef line() As String, ByRef g As Graphics) As Boolean
Dim FormatString As String = "Format: MOVE"
Dim LineString As String = "Line: " & state.LineNumber.ToString & vbCrLf
Select Case line.Length
Case 4
If line(1) <> "TO" Then
ErrorMessage("UNKNOWN MOVE FORMAT")
Return False
End If
If IsNumeric(line(2)) = False Then
Dim MessageText As String = LineString _
& "Error: <X> isn't a number" & vbNewLine _
& "Usage: MOVE TO <X>,<Y>" & vbNewLine _
& "Rules;-" & vbNewLine _
& "1. <X> must be a number." & vbNewLine _
& "2. <Y> must be a number."
ErrorMessage(MessageText)
Return False
End If
If IsNumeric(line(3)) = False Then
Dim MessageText As String = LineString _
& "Error: <Y> isn't a number" & vbNewLine _
& "Usage: MOVE TO <X>,<Y>" & vbNewLine _
& "Rules;-" & vbNewLine _
& "1. <X> must be a number." & vbNewLine _
& "2. <Y> must be a number."
ErrorMessage(MessageText)
Return False
End If
If mState.MakingShape = False Then
If state.PenDown Then DrawLine2(g, state.Width, state.Color, state.X, state.Y, CInt(line(2)), CInt(line(3)))
'Todo: Bound Checks
state.X = CInt(line(2))
state.Y = CInt(line(3))
End If
Return True
Case 3
If IsNumeric(line(1)) = False Then
Dim MessageText As String = LineString _
& "Error: <X> isn't a number" & vbNewLine _
& "Usage: MOVE <X>,<Y>" & vbNewLine _
& "Rules;-" & vbNewLine _
& "1. <X> must be a number." & vbNewLine _
& "2. <Y> must be a number."
ErrorMessage(MessageText)
Return False
End If
If IsNumeric(line(2)) = False Then
Dim MessageText As String = LineString _
& "Error: <Y> isn't a number" & vbNewLine _
& "Usage: MOVE <X>,<Y>" & vbNewLine _
& "Rules;-" & vbNewLine _
& "1. <X> must be a number." & vbNewLine _
& "2. <Y> must be a number."
ErrorMessage(MessageText)
Return False
End If
If mState.MakingShape = False Then
If state.PenDown Then DrawLine(g, state.Width, state.Color, state.X, state.Y, CInt(line(1)), CInt(line(2)))
'Todo: Bound Checks
state.X += CInt(line(1))
state.Y += CInt(line(2))
End If
Return True
Case Else
Dim MessageText As String = LineString _
& "Error: Incorrect number of parameters" & vbNewLine _
& "Usage: MOVE <X>,<Y>" & vbNewLine _
& "Rules;-" & vbNewLine _
& "1. <X> must be a number." & vbNewLine _
& "2. <Y> must be a number."
ErrorMessage(MessageText)
Return False
End Select
End Function
#End Region
#Region "COMMAND: FORWARD"
Private Function Command_Forward(ByRef state As ScriptState, ByRef line() As String, ByRef g As Graphics) As Boolean
' Command: FORWARD <Distance>
' Rules;-
' 1. <Distance> must be a number.
Dim LineString As String = "Line: " & state.LineNumber.ToString & vbCrLf
Select Case line.Length
Case 2
If IsNumeric(line(1)) = False Then
Dim MessageText As String = LineString _
& "Error: <Distance> isn't a number" & vbNewLine _
& "Usage: FORWARD <Distance>" & vbNewLine _
& "Rules;-" & vbNewLine _
& "1. <Distance> must be a number."
ErrorMessage(MessageText)
Return False
Else
If mState.MakingShape = False Then
Dim distance As Double = Val(line(1))
Dim x2 As Double = 0
Dim y2 As Double = 0
x2 = state.X + (distance * Math.Cos(DegreeToRadian(state.Angle + 270)))
y2 = state.Y + (distance * Math.Sin(DegreeToRadian(state.Angle + 270)))
If state.PenDown Then DrawLine2(g, state.Width, state.Color, state.X, state.Y, x2, y2)
'Todo: Bound Checks
state.X = x2
state.Y = y2
Return True
End If
End If
Case Else
' Unrecognised Command
Dim MessageText As String = LineString _
& "Error: Unknown Command" & vbNewLine _
& "Usage: FORWARD <Distance>" & vbNewLine _
& "Rules;-" & vbNewLine _
& "1. <Distance> must be a number."
ErrorMessage(MessageText)
Return False
End Select
Return True
End Function
#End Region
#End Region
#Region "Misc. Useful Functions"
' Convert Radian To Degree
Private Shared Function RadianToDegree(ByVal radian As Double) As Double
Return (180 / Math.PI) * radian
End Function
' Convert Degree to Radian
Private Shared Function DegreeToRadian(ByVal degree As Double) As Double
Return (Math.PI / 180) * degree * 1
End Function
#End Region
End Class
#End Region
The FormIt contains only four controls
1. A RichTextBox called "RTB_Script"
2. A TextBox called "Txt_Output"
3. A PictureBox called "PBox_Outbox"
4. A Button called "But_Execute"
CODE
Public Class Form1
Dim MyScriptEngine As New ScriptEngine
Dim cmds As New List(Of String)
Private Sub But_Execute_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles But_Execute.Click
If Me.RTB_Script.TextLength > 0 TheN
Dim bmp As New Bitmap(PBox_Output.Width, PBox_Output.Height)
Dim pg As Graphics = Graphics.FromImage(bmp)
pg.Clear(Color.White)
cmds.Clear()
cmds.AddRange(RTB_Script.Lines)
MyScriptEngine.ExcuteScript(cmds, pg, Me.Txt_Output)
' MyScriptEngine.ExcuteScript(RTB_Script.Lines.tolist, pg, Me.Txt_Output) 'VB2008
PBox_Output.Image = bmp
pg.Dispose()
End If
End Sub
End Class
This post has been edited by AdamSpeight2008: 11 Jul, 2008 - 03:51 PM