diff --git a/CoreHelpers.tl b/CoreHelpers.tl index 56001ce..34c4ba3 100644 --- a/CoreHelpers.tl +++ b/CoreHelpers.tl @@ -1,9 +1,9 @@ local ds = require("DataStructures") -local Dictionary, Stack, WordInfo, State = ds.Dictionary, ds.Stack, ds.WordInfo, ds.State +local Dictionary, Stack, WordInfo, Environment = ds.Dictionary, ds.Stack, ds.WordInfo, ds.Environment local CoreHelpers = {} -function CoreHelpers.defineWord(dict: Dictionary, str: string, func: function(State, ...: any): any..., imm: boolean) +function CoreHelpers.defineWord(dict: Dictionary, str: string, func: function(Environment, ...: any): any..., imm: boolean) local info = WordInfo:new(func, imm) dict:define(str, info) end @@ -14,7 +14,7 @@ function CoreHelpers.areNumbers(a: any, b: any): boolean return a is number and b is number end -function CoreHelpers.getActiveDataStack(state: State): Stack +function CoreHelpers.getActiveDataStack(state: Environment): Stack return state.activeDataStack end @@ -34,14 +34,14 @@ function CoreHelpers.isWhitespace(chr: string): boolean chr == "\v" or chr == "\f") end -function CoreHelpers.skipWhitespace(state: State) +function CoreHelpers.skipWhitespace(state: Environment) local chr = state.activeInputStream:readCurrentCharacter() while (CoreHelpers.isWhitespace(chr)) do chr = state.activeInputStream:advanceOffset() end end -function CoreHelpers.popTwoOperands(state: State): any, any +function CoreHelpers.popTwoOperands(state: Environment): any, any local stack = CoreHelpers.getActiveDataStack(state) local b: any = stack:pop() local a: any = stack:pop() @@ -49,7 +49,7 @@ function CoreHelpers.popTwoOperands(state: State): any, any end -function CoreHelpers.parseToken(state: State): string +function CoreHelpers.parseToken(state: Environment): string local chr = state.activeInputStream:readCurrentCharacter() local token = "" while(not CoreHelpers.isWhitespace(chr)) do diff --git a/CoreWords.tl b/CoreWords.tl index 82b106c..d20b18b 100644 --- a/CoreWords.tl +++ b/CoreWords.tl @@ -1,12 +1,12 @@ local ds = require("DataStructures") -local Dictionary, Stack, WordInfo, State = ds.Dictionary, ds.Stack, ds.WordInfo, ds.State +local Dictionary, Stack, WordInfo, Environment = ds.Dictionary, ds.Stack, ds.WordInfo, ds.Environment local helpers = require("CoreHelpers") local areNumbers, getActiveDataStack, isNumber, isWhitespace= helpers.areNumbers, helpers.getActiveDataStack, helpers.isNumber, helpers.isWhitespace local skipWhitespace, parseToken = helpers.skipWhitespace, helpers.parseToken local popTwoOperands = helpers.popTwoOperands local defineWord = helpers.defineWord -- Mathematical operations -local function add(state: State) +local function add(state: Environment) local a, b = popTwoOperands(state) if areNumbers(a,b) then local c = (a as number) + (b as number) @@ -15,7 +15,7 @@ local function add(state: State) error("invalid operands for add operation!") end end -local function sub(state: State) +local function sub(state: Environment) local a, b = popTwoOperands(state) if areNumbers(a, b) then local c = (a as number) - (b as number) @@ -24,7 +24,7 @@ local function sub(state: State) error("invalid operands for sub operation!") end end -local function mul(state: State) +local function mul(state: Environment) local a, b = popTwoOperands(state) if areNumbers(a, b) then local c = (a as number) * (b as number) @@ -33,7 +33,7 @@ local function mul(state: State) error("invalid operands for mul operation!") end end -local function div(state: State) +local function div(state: Environment) local a, b = popTwoOperands(state) if areNumbers(a, b) then local c = (a as number) / (b as number) @@ -43,30 +43,30 @@ local function div(state: State) end end -local function dup(state: State) +local function dup(state: Environment) local stack = getActiveDataStack(state) local top = stack:pop() stack:push(top) stack:push(top) end -local function swap(state: State) +local function swap(state: Environment) local stack = getActiveDataStack(state) local a, b = popTwoOperands(state) stack:push(b) stack:push(a) end -local function rot(state: State) +local function rot(state: Environment) local stack = getActiveDataStack(state) local c, b, a= stack:pop(), stack:pop(), stack:pop() stack:push(b) stack:push(c) stack:push(a) end -local function drop(state: State) +local function drop(state: Environment) local stack = getActiveDataStack(state) stack:pop() end -local function over(state: State) +local function over(state: Environment) local stack = getActiveDataStack(state) local b, a = stack:pop(), stack:pop() stack:push(a) @@ -74,15 +74,15 @@ local function over(state: State) stack:push(a) end -- I/O operations -local function dot(state: State) +local function dot(state: Environment) local out = state.activeDataStack:pop() print(out) end -local function twoDup(state: State) +local function twoDup(state: Environment) over(state) over(state) end -local function twoSwap(state: State) +local function twoSwap(state: Environment) local stack = getActiveDataStack(state) local d, c, b, a = stack:pop(), stack:pop(), stack:pop(), stack:pop() stack:push(c) @@ -92,7 +92,7 @@ local function twoSwap(state: State) end -local function twoOver(state: State) +local function twoOver(state: Environment) local stack = getActiveDataStack(state) local d, c, b, a = stack:pop(), stack:pop(), stack:pop(), stack:pop() stack:push(a) @@ -102,16 +102,16 @@ local function twoOver(state: State) stack:push(a) stack:push(b) end -local function nip(state: State) +local function nip(state: Environment) local stack = getActiveDataStack(state) local b, _ = stack:pop(), stack:pop() stack:push(b) end -local function tuck(state: State) +local function tuck(state: Environment) swap(state) over(state) end -local function roll(state: State) +local function roll(state: Environment) local stack = getActiveDataStack(state) local u = stack:pop() local bufferStack = Stack:new() @@ -134,7 +134,7 @@ local function roll(state: State) error("u is not a number") end end -local function getExecutionToken(state: State) +local function getExecutionToken(state: Environment) local stack = getActiveDataStack(state) skipWhitespace(state) local name: string = parseToken(state) @@ -147,9 +147,9 @@ local function getExecutionToken(state: State) end end -local function execute(state: State) +local function execute(state: Environment) local stack = getActiveDataStack(state) - local func: function(State) = stack:pop() as function(State) + local func: function(Environment) = stack:pop() as function(Environment) func(state) end diff --git a/DataStructures.tl b/DataStructures.tl index 7ee3e54..1584310 100644 --- a/DataStructures.tl +++ b/DataStructures.tl @@ -17,57 +17,57 @@ local type DataStructures = record define: function(Dictionary, string, WordInfo) end record WordInfo - func: function(State, ...: any) + func: function(Environment, ...: any) immediate: boolean - new: function(WordInfo, function(State), boolean): WordInfo + new: function(WordInfo, function(Environment), boolean): WordInfo end - record State + record Environment dataStacks: {Stack} compilerStack: Stack activeDataStack: Stack - interrupts: {function(State)} + interrupts: {function(Environment)} activeInputStream: InputStream dictionaries: {Dictionary} state: boolean - new: function(State): State - addDataStack: function(State, Stack) - changeCompilerStack: function(State, Stack) - changeActiveDataStack: function(State, number) + new: function(Environment): Environment + addDataStack: function(Environment, Stack) + changeCompilerStack: function(Environment, Stack) + changeActiveDataStack: function(Environment, number) end end -local Stack, State, Dictionary, WordInfo = DataStructures.Stack, DataStructures.State, DataStructures.Dictionary, DataStructures.WordInfo +local Stack, Environment, Dictionary, WordInfo = DataStructures.Stack, DataStructures.Environment, DataStructures.Dictionary, DataStructures.WordInfo local wordi_mt = {__index = WordInfo} -function WordInfo:new(funct: function(State, ...: any), imm: boolean): WordInfo +function WordInfo:new(funct: function(Environment, ...: any), imm: boolean): WordInfo return setmetatable({func = funct, immediate = imm} as WordInfo, wordi_mt) end -local state_mt = {__index = State} -function State:new(): State +local state_mt = {__index = Environment} +function Environment:new(): Environment return setmetatable( { dataStacks = {}, compilerStack = Stack:new(), dictionaries = {} - } as State, + } as Environment, state_mt) end -function State:addDataStack(data: Stack) +function Environment:addDataStack(data: Stack) table.insert(self.dataStacks, data) end -function State:changeCompilerStack(compilerStack: Stack) +function Environment:changeCompilerStack(compilerStack: Stack) self.compilerStack = compilerStack end ---function State:changeActiveDataStack(stackIndex: number) +--function Environment:changeActiveDataStack(stackIndex: number) -- assert(stackIndex <= #self.dataStacks and stackIndex > 0) -- self.activeDataStack = self.dataStacks[stackIndex] --end diff --git a/ForthInterpreter.tl b/ForthInterpreter.tl index d3942ab..56228a2 100644 --- a/ForthInterpreter.tl +++ b/ForthInterpreter.tl @@ -1,10 +1,10 @@ local CoreWords = require("CoreWords") local ds = require("DataStructures") local istream = require("InputStream") -local Stack, Dictionary, WordInfo, State = ds.Stack, ds.Dictionary, ds.WordInfo, ds.State +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 machineState = State:new() +local machineEnvironment = Environment:new() function standardInputRefill(): string local input = io.read().."\n" @@ -13,21 +13,21 @@ end local standardInputStream = istream:new(standardInputRefill) -machineState.activeInputStream = standardInputStream -machineState.activeDataStack = Stack:new() -table.insert(machineState.dictionaries, CoreWords) +machineEnvironment.activeInputStream = standardInputStream +machineEnvironment.activeDataStack = Stack:new() +table.insert(machineEnvironment.dictionaries, CoreWords) while(true) do - skipWhitespace(machineState) - local token: string = parseToken(machineState) + skipWhitespace(machineEnvironment) + local token: string = parseToken(machineEnvironment) if isNumber(token) then - machineState.activeDataStack:push(tonumber(token)) + machineEnvironment.activeDataStack:push(tonumber(token)) else - for i, dictionary in ipairs(machineState.dictionaries) do + for i, dictionary in ipairs(machineEnvironment.dictionaries) do local wordinfo = dictionary:lookup(token) if wordinfo then - (wordinfo as WordInfo).func(machineState) + (wordinfo as WordInfo).func(machineEnvironment) goto continue end end