Add instruction pointers

This commit is contained in:
Starfflame 2021-05-17 20:59:46 -05:00
parent 6959c473f8
commit e8bcb186e3
3 changed files with 59 additions and 19 deletions

View File

@ -59,5 +59,9 @@ function CoreHelpers.parseToken(state: Environment): string
return token return token
end end
function CoreHelpers.reset(env: Environment)
env.instructionPointer.index = 0 -- will get incremented after this instruction
end
return CoreHelpers return CoreHelpers

View File

@ -22,11 +22,18 @@ local type DataStructures = record
new: function(WordInfo, function(Environment), boolean): WordInfo new: function(WordInfo, function(Environment), boolean): WordInfo
end 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 record Environment
dataStacks: {Stack} dataStacks: {Stack}
compilerStack: Stack compilerStack: Stack
returnStack: Stack
activeDataStack: Stack activeDataStack: Stack
interrupts: {function(Environment)} interrupts: {function(Environment)}
activeInputStream: InputStream activeInputStream: InputStream
@ -37,12 +44,13 @@ local type DataStructures = record
changeCompilerStack: function(Environment, Stack) changeCompilerStack: function(Environment, Stack)
changeActiveDataStack: function(Environment, number) changeActiveDataStack: function(Environment, number)
instructionPointer: Pointer
end end
end end
local Stack, Environment, Dictionary, WordInfo = DataStructures.Stack, DataStructures.Environment, DataStructures.Dictionary, DataStructures.WordInfo local Stack, Environment, Dictionary, WordInfo = DataStructures.Stack, DataStructures.Environment, DataStructures.Dictionary, DataStructures.WordInfo
local Pointer = DataStructures.Pointer
local wordi_mt = {__index = WordInfo} local wordi_mt = {__index = WordInfo}
function WordInfo:new(funct: function(Environment, ...: any), imm: boolean): WordInfo function WordInfo:new(funct: function(Environment, ...: any), imm: boolean): WordInfo
return setmetatable({func = funct, immediate = imm} as WordInfo, wordi_mt) 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) return setmetatable({contents = {}} as Dictionary, dict_mt)
end 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 return DataStructures

View File

@ -4,8 +4,9 @@ local istream = require("InputStream")
local Stack, Dictionary, WordInfo, Environment = ds.Stack, ds.Dictionary, ds.WordInfo, ds.Environment local Stack, Dictionary, WordInfo, Environment = ds.Stack, ds.Dictionary, ds.WordInfo, ds.Environment
local helpers = require("CoreHelpers") local helpers = require("CoreHelpers")
local isNumber, skipWhitespace, parseToken = helpers.isNumber, helpers.skipWhitespace, helpers.parseToken local isNumber, skipWhitespace, parseToken = helpers.isNumber, helpers.skipWhitespace, helpers.parseToken
local reset = helpers.reset
local machineEnvironment = Environment:new() local machineEnvironment = Environment:new()
local Pointer = ds.Pointer
function standardInputRefill(): string function standardInputRefill(): string
local input = io.read().."\n" local input = io.read().."\n"
return input return input
@ -17,17 +18,17 @@ machineEnvironment.activeInputStream = standardInputStream
machineEnvironment.activeDataStack = Stack:new() machineEnvironment.activeDataStack = Stack:new()
table.insert(machineEnvironment.dictionaries, CoreWords) table.insert(machineEnvironment.dictionaries, CoreWords)
function outerInterpreter(env: Environment)
while(true) do while(true) do
skipWhitespace(machineEnvironment) skipWhitespace(env)
local token: string = parseToken(machineEnvironment) local token: string = parseToken(env)
if isNumber(token) then if isNumber(token) then
machineEnvironment.activeDataStack:push(tonumber(token)) env.activeDataStack:push(tonumber(token))
else else
for i, dictionary in ipairs(machineEnvironment.dictionaries) do for i, dictionary in ipairs(env.dictionaries) do
local wordinfo = dictionary:lookup(token) local wordinfo = dictionary:lookup(token)
if wordinfo then if wordinfo then
(wordinfo as WordInfo).func(machineEnvironment) (wordinfo as WordInfo).func(env)
goto continue goto continue
end end
end end
@ -35,5 +36,21 @@ while(true) do
::continue:: ::continue::
end end
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)