From 444a5590cd359f7012ee03330301952129fca798 Mon Sep 17 00:00:00 2001 From: Starfflame Date: Tue, 18 May 2021 22:43:19 -0500 Subject: [PATCH] Add .busted config, seperate interpreter functions from initial setup code for forth machine --- .busted | 4 +++ CoreHelpers.tl | 23 +++++++++++-- CoreWords.tl | 17 ++++++++++ DataStructures.tl | 8 +++-- ForthInterpreter.tl => ForthMachine.tl | 46 +++++++------------------- Interpreters.tl | 38 +++++++++++++++++++++ 6 files changed, 98 insertions(+), 38 deletions(-) create mode 100644 .busted rename ForthInterpreter.tl => ForthMachine.tl (50%) create mode 100644 Interpreters.tl diff --git a/.busted b/.busted new file mode 100644 index 0000000..ad9fcfa --- /dev/null +++ b/.busted @@ -0,0 +1,4 @@ +package.path = "?.lua;"..package.path + +return { +} diff --git a/CoreHelpers.tl b/CoreHelpers.tl index 89c1767..403b8ed 100644 --- a/CoreHelpers.tl +++ b/CoreHelpers.tl @@ -1,6 +1,6 @@ local ds = require("DataStructures") local Dictionary, Stack, WordInfo, Environment = ds.Dictionary, ds.Stack, ds.WordInfo, ds.Environment - +local Pointer = ds.Pointer local CoreHelpers = {} function CoreHelpers.defineWord(dict: Dictionary, str: string, func: function(Environment, ...: any): any..., imm: boolean) @@ -8,7 +8,10 @@ function CoreHelpers.defineWord(dict: Dictionary, str: string, func: function(En dict:define(str, info) end - +function CoreHelpers.standardInputRefill(): string + local input = io.read().."\n" + return input +end function CoreHelpers.areNumbers(a: any, b: any): boolean return a is number and b is number @@ -63,5 +66,21 @@ function CoreHelpers.reset(env: Environment) env.instructionPointer.index = 0 -- will get incremented after this instruction end +function CoreHelpers.ret(env: Environment) + local retAddr = env.returnStack:pop() as Pointer + env.instructionPointer = retAddr +end + +function CoreHelpers.makeCall(body: {function(Environment)}): function(Environment) + return function(e: Environment) + e.returnStack:push(e.instructionPointer) + e.instructionPointer = Pointer:new(body, 0) + end +end + + + + + return CoreHelpers diff --git a/CoreWords.tl b/CoreWords.tl index d20b18b..c07410d 100644 --- a/CoreWords.tl +++ b/CoreWords.tl @@ -5,6 +5,8 @@ local areNumbers, getActiveDataStack, isNumber, isWhitespace= helpers.areNumbers local skipWhitespace, parseToken = helpers.skipWhitespace, helpers.parseToken local popTwoOperands = helpers.popTwoOperands local defineWord = helpers.defineWord +local ret = helpers.ret +local makeCall = helpers.makeCall -- Mathematical operations local function add(state: Environment) local a, b = popTwoOperands(state) @@ -189,6 +191,21 @@ CoreWords:define("2DUP", twoDupInfo) CoreWords:define("2SWAP", twoSwapInfo) CoreWords:define("2OVER", twoOverInfo) CoreWords:define("NIP", nipInfo) + + + +local sqr = {dup, mul, ret} +local sqrf = makeCall(sqr) + +defineWord(CoreWords, "SQR", sqrf, false) + + + + + + + + return CoreWords diff --git a/DataStructures.tl b/DataStructures.tl index c08c581..441795c 100644 --- a/DataStructures.tl +++ b/DataStructures.tl @@ -27,7 +27,7 @@ local type DataStructures = record referant: {number: any} deref: function(self: Pointer): any inc: function(self: Pointer) - new: function(self: Pointer): Pointer + new: function(self: Pointer, body: {function(Environment)}, idx: number): Pointer end record Environment @@ -127,7 +127,11 @@ local pointer_mt = {__index = Pointer} function Pointer:new(): Pointer return setmetatable({referant = {}, index = 1} as Pointer, pointer_mt) end - +function Pointer:new(body: {function(Environment)}, idx: number): Pointer + local tbl = body or {} + local jdx = idx or 1 + return setmetatable({referant = tbl, index = jdx} as Pointer, pointer_mt) +end return DataStructures diff --git a/ForthInterpreter.tl b/ForthMachine.tl similarity index 50% rename from ForthInterpreter.tl rename to ForthMachine.tl index a6c20d0..959f21d 100644 --- a/ForthInterpreter.tl +++ b/ForthMachine.tl @@ -3,54 +3,32 @@ local ds = require("DataStructures") local istream = require("InputStream") local Stack, Dictionary, WordInfo, Environment = ds.Stack, ds.Dictionary, ds.WordInfo, ds.Environment local helpers = require("CoreHelpers") +local interpreters = require("Interpreters") 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 -end +local standardInputRefill = helpers.standardInputRefill +local innerInterpreter, outerInterpreter = interpreters.inner, interpreters.outer + + +local machineEnvironment = Environment:new() local standardInputStream = istream:new(standardInputRefill) machineEnvironment.activeInputStream = standardInputStream machineEnvironment.activeDataStack = Stack:new() +machineEnvironment.returnStack = Stack:new() + table.insert(machineEnvironment.dictionaries, CoreWords) -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 - 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 interpreterInstructions = {} +table.insert(interpreterInstructions, outerInterpreter) +table.insert(interpreterInstructions, reset) local startPointer = Pointer:new() startPointer.referant = interpreterInstructions -startPointer.index = 0 machineEnvironment.instructionPointer = startPointer +innerInterpreter(machineEnvironment) -outerInterpreter(machineEnvironment) diff --git a/Interpreters.tl b/Interpreters.tl new file mode 100644 index 0000000..6516979 --- /dev/null +++ b/Interpreters.tl @@ -0,0 +1,38 @@ +local ds = require("DataStructures") +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 type Interpreters = record + inner: function(Environment) + outer: function(Environment) +end + + + +function Interpreters.outer(env: Environment) + skipWhitespace(env) + local token: string = parseToken(env) + if isNumber(token) then + env.activeDataStack:push(tonumber(token)) + else + for _, 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 +end + +function Interpreters.inner(env: Environment) + while(true) do + env.instructionPointer:deref() as function(Environment)(env) + env.instructionPointer:inc() + end +end + +return Interpreters