Add words for [ and ]

This commit is contained in:
Starfflame 2021-05-25 02:27:57 -05:00
parent c2c9a6bcc2
commit 7fa57cf474
4 changed files with 99 additions and 50 deletions

View File

@ -15,6 +15,7 @@ function CoreHelpers.standardInputRefill(): string
return input return input
end end
function CoreHelpers._oneReadRefill(str: string): function(): string function CoreHelpers._oneReadRefill(str: string): function(): string
local alreadyRead: boolean = false local alreadyRead: boolean = false
return function(): string return function(): string
@ -115,6 +116,14 @@ end
function CoreHelpers.recNumber(env: Environment)
local dataStack = CoreHelpers.getActiveDataStack(env)
local token = dataStack:pop() as string
if CoreHelpers.isNumber(token) then
-- push the XTs onto the stack
dataStack:push(true)
end
end
return CoreHelpers return CoreHelpers

View File

@ -8,84 +8,83 @@ local defineWord = helpers.defineWord
local ret = helpers.ret local ret = helpers.ret
local makeCall = helpers.makeCall local makeCall = helpers.makeCall
-- Mathematical operations -- Mathematical operations
local function add(state: Environment) local function add(env: Environment)
local a, b = popTwoOperands(state) local a, b = popTwoOperands(env)
if areNumbers(a,b) then if areNumbers(a,b) then
local c = (a as number) + (b as number) local c = (a as number) + (b as number)
getActiveDataStack(state):push(c) getActiveDataStack(env):push(c)
else else
error("invalid operands for add operation!") error("invalid operands for add operation!")
end end
end end
local function sub(state: Environment) local function sub(env: Environment)
local a, b = popTwoOperands(state) local a, b = popTwoOperands(env)
if areNumbers(a, b) then if areNumbers(a, b) then
local c = (a as number) - (b as number) local c = (a as number) - (b as number)
getActiveDataStack(state):push(c) getActiveDataStack(env):push(c)
else else
error("invalid operands for sub operation!") error("invalid operands for sub operation!")
end end
end end
local function mul(state: Environment) local function mul(env: Environment)
local a, b = popTwoOperands(state) local a, b = popTwoOperands(env)
if areNumbers(a, b) then if areNumbers(a, b) then
local c = (a as number) * (b as number) local c = (a as number) * (b as number)
getActiveDataStack(state):push(c) getActiveDataStack(env):push(c)
else else
error("invalid operands for mul operation!") error("invalid operands for mul operation!")
end end
end end
local function div(state: Environment) local function div(env: Environment)
local a, b = popTwoOperands(state) local a, b = popTwoOperands(env)
if areNumbers(a, b) then if areNumbers(a, b) then
local c = (a as number) / (b as number) local c = (a as number) / (b as number)
getActiveDataStack(state):push(c) getActiveDataStack(env):push(c)
else else
error("invalid operands for div operation!") error("invalid operands for div operation!")
end end
end end
local function dup(state: Environment) local function dup(env: Environment)
local stack = getActiveDataStack(state) local stack = getActiveDataStack(env)
local top = stack:pop() local top = stack:pop()
stack:push(top) stack:push(top)
stack:push(top) stack:push(top)
end end
local function swap(state: Environment) local function swap(env: Environment)
local stack = getActiveDataStack(state) local stack = getActiveDataStack(env)
local a, b = popTwoOperands(state) local a, b = popTwoOperands(env)
stack:push(b) stack:push(b)
stack:push(a) stack:push(a)
end end
local function rot(state: Environment) local function rot(env: Environment)
local stack = getActiveDataStack(state) local stack = getActiveDataStack(env)
local c, b, a= stack:pop(), stack:pop(), stack:pop() local c, b, a= stack:pop(), stack:pop(), stack:pop()
stack:push(b) stack:push(b)
stack:push(c) stack:push(c)
stack:push(a) stack:push(a)
end end
local function drop(state: Environment) local function drop(env: Environment)
local stack = getActiveDataStack(state) local stack = getActiveDataStack(env)
stack:pop() stack:pop()
end end
local function over(state: Environment) local function over(env: Environment)
local stack = getActiveDataStack(state) local stack = getActiveDataStack(env)
local b, a = stack:pop(), stack:pop() local b, a = stack:pop(), stack:pop()
stack:push(a) stack:push(a)
stack:push(b) stack:push(b)
stack:push(a) stack:push(a)
end end
-- I/O operations -- I/O operations
local function dot(state: Environment) local function dot(env: Environment)
local out = state.activeDataStack:pop() local out = env.activeDataStack:pop()
io.write(tostring(out) as string.."\n") io.write(tostring(out) as string.."\n")
end end
local function twoDup(state: Environment)
over(state) local twoDup = helpers.makeCall{over, over, ret}
over(state)
end local function twoSwap(env: Environment)
local function twoSwap(state: Environment) local stack = getActiveDataStack(env)
local stack = getActiveDataStack(state)
local d, c, b, a = stack:pop(), stack:pop(), stack:pop(), stack:pop() local d, c, b, a = stack:pop(), stack:pop(), stack:pop(), stack:pop()
stack:push(c) stack:push(c)
stack:push(d) stack:push(d)
@ -94,8 +93,8 @@ local function twoSwap(state: Environment)
end end
local function twoOver(state: Environment) local function twoOver(env: Environment)
local stack = getActiveDataStack(state) local stack = getActiveDataStack(env)
local d, c, b, a = stack:pop(), stack:pop(), stack:pop(), stack:pop() local d, c, b, a = stack:pop(), stack:pop(), stack:pop(), stack:pop()
stack:push(a) stack:push(a)
stack:push(b) stack:push(b)
@ -104,17 +103,16 @@ local function twoOver(state: Environment)
stack:push(a) stack:push(a)
stack:push(b) stack:push(b)
end end
local function nip(state: Environment) local function nip(env: Environment)
local stack = getActiveDataStack(state) local stack = getActiveDataStack(env)
local b, _ = stack:pop(), stack:pop() local b, _ = stack:pop(), stack:pop()
stack:push(b) stack:push(b)
end end
local function tuck(state: Environment)
swap(state) local tuck = helpers.makeCall{swap, over, ret}
over(state)
end local function roll(env: Environment)
local function roll(state: Environment) local stack = getActiveDataStack(env)
local stack = getActiveDataStack(state)
local u = stack:pop() local u = stack:pop()
local bufferStack = Stack:new() local bufferStack = Stack:new()
if u is number then if u is number then
@ -136,11 +134,11 @@ local function roll(state: Environment)
error("u is not a number") error("u is not a number")
end end
end end
local function getExecutionToken(state: Environment) local function getExecutionToken(env: Environment)
local stack = getActiveDataStack(state) local stack = getActiveDataStack(env)
skipWhitespace(state) skipWhitespace(env)
local name: string = parseToken(state) local name: string = parseToken(env)
for _, dictionary in ipairs(state.dictionaries) do for _, dictionary in ipairs(env.dictionaries) do
local wordinfo = dictionary:lookup(name) local wordinfo = dictionary:lookup(name)
if wordinfo then if wordinfo then
stack:push((wordinfo as WordInfo).func) stack:push((wordinfo as WordInfo).func)
@ -149,10 +147,34 @@ local function getExecutionToken(state: Environment)
end end
end end
local function execute(state: Environment) local function execute(env: Environment)
local stack = getActiveDataStack(state) local stack = getActiveDataStack(env)
local func: function(Environment) = stack:pop() as function(Environment) local func: function(Environment) = stack:pop() as function(Environment)
func(state) func(env)
end
local function enterCompileMode(e: Environment)
e.compileState = true
end
local function exitCompileMode(e: Environment)
e.compileState = false
end
local function compile(env: Environment)
end
local function literal(env: Environment)
local stack = env.activeDataStack
local fun = function(e: Environment)
end
end
local function postpone(env: Environment)
end end
local CoreWords = Dictionary:new() local CoreWords = Dictionary:new()
@ -175,6 +197,8 @@ defineWord(CoreWords, "TUCK", tuck, false)
defineWord(CoreWords, "ROLL", roll, false) defineWord(CoreWords, "ROLL", roll, false)
defineWord(CoreWords, "'", getExecutionToken, false) defineWord(CoreWords, "'", getExecutionToken, false)
defineWord(CoreWords, "EXECUTE", execute, false) defineWord(CoreWords, "EXECUTE", execute, false)
defineWord(CoreWords, "[", exitCompileMode, false)
defineWord(CoreWords, "]", enterCompileMode, false)
CoreWords:define("+", addInfo) CoreWords:define("+", addInfo)
CoreWords:define("-", subInfo) CoreWords:define("-", subInfo)

View File

@ -38,7 +38,7 @@ local type DataStructures = record
interrupts: {function(Environment)} interrupts: {function(Environment)}
activeInputStream: InputStream activeInputStream: InputStream
dictionaries: {Dictionary} dictionaries: {Dictionary}
state: boolean compileState: boolean
new: function(Environment): Environment new: function(Environment): Environment
addDataStack: function(Environment, Stack) addDataStack: function(Environment, Stack)
changeCompilerStack: function(Environment, Stack) changeCompilerStack: function(Environment, Stack)

View File

@ -390,6 +390,22 @@ describe("Interpreter tests", function()
assert.are.equal(3, testEnv.activeDataStack.contents[1]) assert.are.equal(3, testEnv.activeDataStack.contents[1])
end) end)
end) end)
describe("[ tests", function()
it("Switches the environment's state to interpretation mode.", function()
local testEnv = buildEnvironment("[")
testEnv.compileState = true
interpreters.start(testEnv)
assert.are.equal(false, testEnv.compileState)
end)
end)
describe("] tests", function()
it("Switches the environment's state to compilation mode.", function()
local testEnv = buildEnvironment("]")
testEnv.compileState = false
interpreters.start(testEnv)
assert.are.equal(true, testEnv.compileState)
end)
end)
end) end)
end) end)