2021-05-11 08:19:54 +00:00
|
|
|
local Dictionary = require("Dictionary")
|
2021-05-11 06:55:13 +00:00
|
|
|
local Stack = require("Stack")
|
2021-05-11 08:19:54 +00:00
|
|
|
local WordInfo = require("WordInfo")
|
|
|
|
local State = require("State")
|
2021-05-11 06:55:13 +00:00
|
|
|
|
2021-05-11 08:19:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
-- helper functions
|
|
|
|
function areNumbers(a: any, b: any): boolean
|
|
|
|
return a is number and b is number
|
|
|
|
end
|
|
|
|
function getActiveDataStack(state: State): Stack
|
|
|
|
return state.activeDataStack
|
|
|
|
end
|
|
|
|
function popTwoOperands(state: State): any, any
|
|
|
|
local stack = getActiveDataStack(state)
|
|
|
|
local b: any = stack:pop()
|
|
|
|
local a: any = stack:pop()
|
|
|
|
return a, b
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- Mathematical operations
|
|
|
|
function add(state: State)
|
|
|
|
local a, b = popTwoOperands(state)
|
|
|
|
if areNumbers(a,b) then
|
|
|
|
local c = (a as number) + (b as number)
|
|
|
|
getActiveDataStack(state):push(c)
|
2021-05-11 06:58:09 +00:00
|
|
|
else
|
|
|
|
error("invalid operands for add operation!")
|
|
|
|
end
|
|
|
|
end
|
2021-05-11 08:19:54 +00:00
|
|
|
function sub(state: State)
|
|
|
|
local a, b = popTwoOperands(state)
|
|
|
|
if areNumbers(a, b) then
|
|
|
|
local c = (a as number) - (b as number)
|
|
|
|
getActiveDataStack(state):push(c)
|
|
|
|
else
|
|
|
|
error("invalid operands for sub operation!")
|
|
|
|
end
|
2021-05-11 06:58:09 +00:00
|
|
|
end
|
2021-05-11 08:19:54 +00:00
|
|
|
function mul(state: State)
|
|
|
|
local a, b = popTwoOperands(state)
|
|
|
|
if areNumbers(a, b) then
|
|
|
|
local c = (a as number) * (b as number)
|
|
|
|
getActiveDataStack(state):push(c)
|
|
|
|
else
|
|
|
|
error("invalid operands for mul operation!")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
function div(state: State)
|
|
|
|
local a, b = popTwoOperands(state)
|
|
|
|
if areNumbers(a, b) then
|
|
|
|
local c = (a as number) / (b as number)
|
|
|
|
getActiveDataStack(state):push(c)
|
|
|
|
else
|
|
|
|
error("invalid operands for div operation!")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
-- I/O operations
|
|
|
|
function dot(state: State)
|
|
|
|
local out = state.activeDataStack:pop()
|
|
|
|
print(out)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
local CoreWords = Dictionary:new()
|
|
|
|
local AddInfo = WordInfo:new(add, false)
|
|
|
|
local SubInfo = WordInfo:new(sub, false)
|
|
|
|
local MulInfo = WordInfo:new(mul, false)
|
|
|
|
local DivInfo = WordInfo:new(div, false)
|
|
|
|
|
|
|
|
CoreWords:define("+", AddInfo)
|
|
|
|
CoreWords:define("-", SubInfo)
|
|
|
|
CoreWords:define("*", MulInfo)
|
|
|
|
CoreWords:define("/", DivInfo)
|
|
|
|
|
|
|
|
return CoreWords
|
|
|
|
|
2021-05-11 06:55:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
|