Compare commits
2 Commits
c2c9a6bcc2
...
70e8c7e959
Author | SHA1 | Date |
---|---|---|
Starfflame | 70e8c7e959 | |
Starfflame | 7fa57cf474 |
|
@ -15,6 +15,7 @@ function CoreHelpers.standardInputRefill(): string
|
|||
return input
|
||||
end
|
||||
|
||||
|
||||
function CoreHelpers._oneReadRefill(str: string): function(): string
|
||||
local alreadyRead: boolean = false
|
||||
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
|
||||
|
|
129
CoreWords.tl
129
CoreWords.tl
|
@ -8,84 +8,83 @@ local defineWord = helpers.defineWord
|
|||
local ret = helpers.ret
|
||||
local makeCall = helpers.makeCall
|
||||
-- Mathematical operations
|
||||
local function add(state: Environment)
|
||||
local a, b = popTwoOperands(state)
|
||||
local function add(env: Environment)
|
||||
local a, b = popTwoOperands(env)
|
||||
if areNumbers(a,b) then
|
||||
local c = (a as number) + (b as number)
|
||||
getActiveDataStack(state):push(c)
|
||||
getActiveDataStack(env):push(c)
|
||||
else
|
||||
error("invalid operands for add operation!")
|
||||
end
|
||||
end
|
||||
local function sub(state: Environment)
|
||||
local a, b = popTwoOperands(state)
|
||||
local function sub(env: Environment)
|
||||
local a, b = popTwoOperands(env)
|
||||
if areNumbers(a, b) then
|
||||
local c = (a as number) - (b as number)
|
||||
getActiveDataStack(state):push(c)
|
||||
getActiveDataStack(env):push(c)
|
||||
else
|
||||
error("invalid operands for sub operation!")
|
||||
end
|
||||
end
|
||||
local function mul(state: Environment)
|
||||
local a, b = popTwoOperands(state)
|
||||
local function mul(env: Environment)
|
||||
local a, b = popTwoOperands(env)
|
||||
if areNumbers(a, b) then
|
||||
local c = (a as number) * (b as number)
|
||||
getActiveDataStack(state):push(c)
|
||||
getActiveDataStack(env):push(c)
|
||||
else
|
||||
error("invalid operands for mul operation!")
|
||||
end
|
||||
end
|
||||
local function div(state: Environment)
|
||||
local a, b = popTwoOperands(state)
|
||||
local function div(env: Environment)
|
||||
local a, b = popTwoOperands(env)
|
||||
if areNumbers(a, b) then
|
||||
local c = (a as number) / (b as number)
|
||||
getActiveDataStack(state):push(c)
|
||||
getActiveDataStack(env):push(c)
|
||||
else
|
||||
error("invalid operands for div operation!")
|
||||
end
|
||||
end
|
||||
|
||||
local function dup(state: Environment)
|
||||
local stack = getActiveDataStack(state)
|
||||
local function dup(env: Environment)
|
||||
local stack = getActiveDataStack(env)
|
||||
local top = stack:pop()
|
||||
stack:push(top)
|
||||
stack:push(top)
|
||||
end
|
||||
local function swap(state: Environment)
|
||||
local stack = getActiveDataStack(state)
|
||||
local a, b = popTwoOperands(state)
|
||||
local function swap(env: Environment)
|
||||
local stack = getActiveDataStack(env)
|
||||
local a, b = popTwoOperands(env)
|
||||
stack:push(b)
|
||||
stack:push(a)
|
||||
end
|
||||
local function rot(state: Environment)
|
||||
local stack = getActiveDataStack(state)
|
||||
local function rot(env: Environment)
|
||||
local stack = getActiveDataStack(env)
|
||||
local c, b, a= stack:pop(), stack:pop(), stack:pop()
|
||||
stack:push(b)
|
||||
stack:push(c)
|
||||
stack:push(a)
|
||||
end
|
||||
local function drop(state: Environment)
|
||||
local stack = getActiveDataStack(state)
|
||||
local function drop(env: Environment)
|
||||
local stack = getActiveDataStack(env)
|
||||
stack:pop()
|
||||
end
|
||||
local function over(state: Environment)
|
||||
local stack = getActiveDataStack(state)
|
||||
local function over(env: Environment)
|
||||
local stack = getActiveDataStack(env)
|
||||
local b, a = stack:pop(), stack:pop()
|
||||
stack:push(a)
|
||||
stack:push(b)
|
||||
stack:push(a)
|
||||
end
|
||||
-- I/O operations
|
||||
local function dot(state: Environment)
|
||||
local out = state.activeDataStack:pop()
|
||||
local function dot(env: Environment)
|
||||
local out = env.activeDataStack:pop()
|
||||
io.write(tostring(out) as string.."\n")
|
||||
end
|
||||
local function twoDup(state: Environment)
|
||||
over(state)
|
||||
over(state)
|
||||
end
|
||||
local function twoSwap(state: Environment)
|
||||
local stack = getActiveDataStack(state)
|
||||
|
||||
local twoDup = helpers.makeCall{over, over, ret}
|
||||
|
||||
local function twoSwap(env: Environment)
|
||||
local stack = getActiveDataStack(env)
|
||||
local d, c, b, a = stack:pop(), stack:pop(), stack:pop(), stack:pop()
|
||||
stack:push(c)
|
||||
stack:push(d)
|
||||
|
@ -94,8 +93,8 @@ local function twoSwap(state: Environment)
|
|||
end
|
||||
|
||||
|
||||
local function twoOver(state: Environment)
|
||||
local stack = getActiveDataStack(state)
|
||||
local function twoOver(env: Environment)
|
||||
local stack = getActiveDataStack(env)
|
||||
local d, c, b, a = stack:pop(), stack:pop(), stack:pop(), stack:pop()
|
||||
stack:push(a)
|
||||
stack:push(b)
|
||||
|
@ -104,17 +103,16 @@ local function twoOver(state: Environment)
|
|||
stack:push(a)
|
||||
stack:push(b)
|
||||
end
|
||||
local function nip(state: Environment)
|
||||
local stack = getActiveDataStack(state)
|
||||
local function nip(env: Environment)
|
||||
local stack = getActiveDataStack(env)
|
||||
local b, _ = stack:pop(), stack:pop()
|
||||
stack:push(b)
|
||||
end
|
||||
local function tuck(state: Environment)
|
||||
swap(state)
|
||||
over(state)
|
||||
end
|
||||
local function roll(state: Environment)
|
||||
local stack = getActiveDataStack(state)
|
||||
|
||||
local tuck = helpers.makeCall{swap, over, ret}
|
||||
|
||||
local function roll(env: Environment)
|
||||
local stack = getActiveDataStack(env)
|
||||
local u = stack:pop()
|
||||
local bufferStack = Stack:new()
|
||||
if u is number then
|
||||
|
@ -136,11 +134,11 @@ local function roll(state: Environment)
|
|||
error("u is not a number")
|
||||
end
|
||||
end
|
||||
local function getExecutionToken(state: Environment)
|
||||
local stack = getActiveDataStack(state)
|
||||
skipWhitespace(state)
|
||||
local name: string = parseToken(state)
|
||||
for _, dictionary in ipairs(state.dictionaries) do
|
||||
local function getExecutionToken(env: Environment)
|
||||
local stack = getActiveDataStack(env)
|
||||
skipWhitespace(env)
|
||||
local name: string = parseToken(env)
|
||||
for _, dictionary in ipairs(env.dictionaries) do
|
||||
local wordinfo = dictionary:lookup(name)
|
||||
if wordinfo then
|
||||
stack:push((wordinfo as WordInfo).func)
|
||||
|
@ -149,10 +147,38 @@ local function getExecutionToken(state: Environment)
|
|||
end
|
||||
end
|
||||
|
||||
local function execute(state: Environment)
|
||||
local stack = getActiveDataStack(state)
|
||||
local function execute(env: Environment)
|
||||
local stack = getActiveDataStack(env)
|
||||
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)
|
||||
local stack = env.activeDataStack
|
||||
local f = stack:pop() as function(Environment)
|
||||
table.insert(env.currentDefinition, f)
|
||||
end
|
||||
local function literal(env: Environment)
|
||||
local stack = env.activeDataStack
|
||||
local val = stack:pop()
|
||||
local fun = function(e: Environment)
|
||||
local s = e.activeDataStack
|
||||
s:push(val)
|
||||
end
|
||||
table.insert(env.currentDefinition, fun)
|
||||
end
|
||||
|
||||
local function postpone(env: Environment)
|
||||
|
||||
|
||||
end
|
||||
|
||||
local CoreWords = Dictionary:new()
|
||||
|
@ -175,6 +201,11 @@ defineWord(CoreWords, "TUCK", tuck, false)
|
|||
defineWord(CoreWords, "ROLL", roll, false)
|
||||
defineWord(CoreWords, "'", getExecutionToken, false)
|
||||
defineWord(CoreWords, "EXECUTE", execute, false)
|
||||
defineWord(CoreWords, "[", exitCompileMode, true)
|
||||
defineWord(CoreWords, "]", enterCompileMode, false)
|
||||
defineWord(CoreWords, "COMPILE,", compile, true)
|
||||
defineWord(CoreWords, "LITERAL", literal, true)
|
||||
|
||||
|
||||
CoreWords:define("+", addInfo)
|
||||
CoreWords:define("-", subInfo)
|
||||
|
|
|
@ -38,7 +38,7 @@ local type DataStructures = record
|
|||
interrupts: {function(Environment)}
|
||||
activeInputStream: InputStream
|
||||
dictionaries: {Dictionary}
|
||||
state: boolean
|
||||
compileState: boolean
|
||||
new: function(Environment): Environment
|
||||
addDataStack: function(Environment, Stack)
|
||||
changeCompilerStack: function(Environment, Stack)
|
||||
|
@ -46,6 +46,8 @@ local type DataStructures = record
|
|||
recognizers: {function(Environment)}
|
||||
instructionPointer: Pointer
|
||||
running: boolean
|
||||
|
||||
currentDefinition: {function(Environment)}
|
||||
end
|
||||
|
||||
end
|
||||
|
|
16
tests.lua
16
tests.lua
|
@ -390,6 +390,22 @@ describe("Interpreter tests", function()
|
|||
assert.are.equal(3, testEnv.activeDataStack.contents[1])
|
||||
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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue