Results 1 to 2 of 2

Thread: Simple programmable stack machine in VB.Net

Threaded View

  1. #1

    Thread Starter
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Simple programmable stack machine in VB.Net

    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
    
    See comment on top of the code for a description of what this is about.
    Last edited by Niya; Oct 29th, 2025 at 08:45 PM.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width