See comment on top of the code for a description of what this is about.Code:Imports System.Runtime.CompilerServices Public Class Form1 '********************************************************** 'This application demonstrates how we can use delegates and anonymous functions 'to create a programmaable stack machine without having to create a language 'parser or do lexical analysis etc. Effectively the host language, in this case 'VB.Net, IS your scripting language. It's not just limited to stack machines. You can 'create any kind of programmable computer within your program. It's particularly useful 'in video game systems as it allows you to create programmable entities 'in a generalized engine. What this means is that you can create a sophisticated game world 'while keeping the engine itself isolated and relatively simple. '********************************************************** Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim pt1 = New PointF(0, 0) Dim pt2 = New PointF(25, 26) 'Calculate distance using our stack machine Debug.WriteLine(CalcDist(pt1, pt2)) 'We use this to verify our stack machine 'program produces the correct result Debug.WriteLine(Math.Sqrt(((pt2.X - pt1.X) ^ 2) + (pt2.Y - pt1.Y) ^ 2)) End Sub Private Function CalcDist(ByVal pt1 As PointF, ByVal pt2 As PointF) As Single 'This function calculates the distance between two points 'using a programmable stack machine for expression evaluation '***************************************************************** Dim l As New List(Of SMInst) '(x2-x1)^2 l.Add(Sub(sm) sm.OP_Push(pt2.X)) l.Add(Sub(sm) sm.OP_Push(pt1.X)) l.Add(Sub(sm) sm.OP_SUB()) l.Add(Sub(sm) sm.OP_Push(2)) l.Add(Sub(sm) sm.OP_POW()) '(y2-y1)^2 l.Add(Sub(sm) sm.OP_Push(pt2.Y)) l.Add(Sub(sm) sm.OP_Push(pt1.Y)) l.Add(Sub(sm) sm.OP_SUB()) l.Add(Sub(sm) sm.OP_Push(2)) l.Add(Sub(sm) sm.OP_POW()) 'Add the results of both calculations l.Add(Sub(sm) sm.OP_Add()) 'Get the square root of the result l.Add(Sub(sm) sm.OP_SQR()) Return Eval(l) End Function Private Function Eval(ByVal program As IEnumerable(Of SMInst)) As Single Dim sm As New StackMachine sm.ExecuteProgram(program) Return sm.OP_Pop() End Function End Class 'Stack machine instruction Public Delegate Sub SMInst(ByVal sm As StackMachine) Public Class StackMachine Private _stack As New Stack(Of Single) Public Sub ExecuteProgram(ByVal program As IEnumerable(Of SMInst)) For Each instruction As SMInst In program instruction.Invoke(Me) Next End Sub Public Sub OP_Push(ByVal operand As Single) _stack.Push(operand) End Sub Public Function OP_Pop() As Single Return _stack.Pop() End Function Public Sub OP_SQR() OP_Push(Math.Sqrt(OP_Pop())) End Sub Public Sub OP_Add() _stack.Push(OP_Pop() + OP_Pop()) End Sub Public Sub OP_SUB() Dim r = OP_Pop() Dim l = OP_Pop() OP_Push(l - r) End Sub Public Sub OP_DIV() Dim r = OP_Pop() Dim l = OP_Pop() OP_Push(l / r) End Sub Public Sub OP_MUL() _stack.Push(OP_Pop() * OP_Pop()) End Sub Public Sub OP_POW() Dim r = OP_Pop() Dim l = OP_Pop() OP_Push(l ^ r) End Sub End Class




Reply With Quote