From e8bcb186e31156cc2fbf27d51b3760d27a6d2669 Mon Sep 17 00:00:00 2001 From: Starfflame Date: Mon, 17 May 2021 20:59:46 -0500 Subject: [PATCH] Add instruction pointers --- CoreHelpers.tl | 4 ++++ DataStructures.tl | 25 ++++++++++++++++++++--- ForthInterpreter.tl | 49 ++++++++++++++++++++++++++++++--------------- 3 files changed, 59 insertions(+), 19 deletions(-) diff --git a/CoreHelpers.tl b/CoreHelpers.tl index 34c4ba3..89c1767 100644 --- a/CoreHelpers.tl +++ b/CoreHelpers.tl @@ -59,5 +59,9 @@ function CoreHelpers.parseToken(state: Environment): string return token end +function CoreHelpers.reset(env: Environment) + env.instructionPointer.index = 0 -- will get incremented after this instruction +end + return CoreHelpers diff --git a/DataStructures.tl b/DataStructures.tl index 1584310..c08c581 100644 --- a/DataStructures.tl +++ b/DataStructures.tl @@ -22,11 +22,18 @@ local type DataStructures = record new: function(WordInfo, function(Environment), boolean): WordInfo end - + record Pointer + index: number + referant: {number: any} + deref: function(self: Pointer): any + inc: function(self: Pointer) + new: function(self: Pointer): Pointer + end record Environment dataStacks: {Stack} compilerStack: Stack + returnStack: Stack activeDataStack: Stack interrupts: {function(Environment)} activeInputStream: InputStream @@ -36,13 +43,14 @@ local type DataStructures = record addDataStack: function(Environment, Stack) changeCompilerStack: function(Environment, Stack) changeActiveDataStack: function(Environment, number) - + + instructionPointer: Pointer end end local Stack, Environment, Dictionary, WordInfo = DataStructures.Stack, DataStructures.Environment, DataStructures.Dictionary, DataStructures.WordInfo - +local Pointer = DataStructures.Pointer local wordi_mt = {__index = WordInfo} function WordInfo:new(funct: function(Environment, ...: any), imm: boolean): WordInfo return setmetatable({func = funct, immediate = imm} as WordInfo, wordi_mt) @@ -109,6 +117,17 @@ function Dictionary:new(): Dictionary return setmetatable({contents = {}} as Dictionary, dict_mt) end +function Pointer:deref(): any + return self.referant[self.index] +end +function Pointer:inc() + self.index = self.index + 1 +end +local pointer_mt = {__index = Pointer} +function Pointer:new(): Pointer + return setmetatable({referant = {}, index = 1} as Pointer, pointer_mt) +end + return DataStructures diff --git a/ForthInterpreter.tl b/ForthInterpreter.tl index 56228a2..a6c20d0 100644 --- a/ForthInterpreter.tl +++ b/ForthInterpreter.tl @@ -4,8 +4,9 @@ local istream = require("InputStream") local Stack, Dictionary, WordInfo, Environment = ds.Stack, ds.Dictionary, ds.WordInfo, ds.Environment local helpers = require("CoreHelpers") local isNumber, skipWhitespace, parseToken = helpers.isNumber, helpers.skipWhitespace, helpers.parseToken +local reset = helpers.reset local machineEnvironment = Environment:new() - +local Pointer = ds.Pointer function standardInputRefill(): string local input = io.read().."\n" return input @@ -17,23 +18,39 @@ machineEnvironment.activeInputStream = standardInputStream machineEnvironment.activeDataStack = Stack:new() table.insert(machineEnvironment.dictionaries, CoreWords) - -while(true) do - skipWhitespace(machineEnvironment) - local token: string = parseToken(machineEnvironment) - if isNumber(token) then - machineEnvironment.activeDataStack:push(tonumber(token)) - else - for i, dictionary in ipairs(machineEnvironment.dictionaries) do - local wordinfo = dictionary:lookup(token) - if wordinfo then - (wordinfo as WordInfo).func(machineEnvironment) - goto continue +function outerInterpreter(env: Environment) + while(true) do + skipWhitespace(env) + local token: string = parseToken(env) + if isNumber(token) then + env.activeDataStack:push(tonumber(token)) + else + for i, dictionary in ipairs(env.dictionaries) do + local wordinfo = dictionary:lookup(token) + if wordinfo then + (wordinfo as WordInfo).func(env) + goto continue + end end + print(string.format('%q ?', token)) + ::continue:: end - print(string.format('%q ?', token)) - ::continue:: - end + end end +function innerInterpreter(env: Environment) + while(true) do + (env.instructionPointer:deref() as function(Environment))(env) + env.instructionPointer:inc() + end +end +local interpreterInstructions = {outerInterpreter, reset} +local startPointer = Pointer:new() +startPointer.referant = interpreterInstructions +startPointer.index = 0 + +machineEnvironment.instructionPointer = startPointer + + +outerInterpreter(machineEnvironment)