diff --git a/CoreWords.tl b/CoreWords.tl index 2c17349..c24258b 100644 --- a/CoreWords.tl +++ b/CoreWords.tl @@ -1,19 +1,82 @@ -local Dict = require("Dictionary") +local Dictionary = require("Dictionary") local Stack = require("Stack") +local WordInfo = require("WordInfo") +local State = require("State") -function add(stack: Stack) - local a: any =stack:pop() - local b: any=stack:pop() - if a is number and b is number then - local c=a+b - stack:push(c) + + +-- 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) else error("invalid operands for add operation!") end end -function dot(s: Stack) - print(s:pop()) +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 +end +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 + + diff --git a/WordInfo.tl b/WordInfo.tl index a287395..10b550b 100644 --- a/WordInfo.tl +++ b/WordInfo.tl @@ -5,7 +5,7 @@ local type WordInfo = record immediate: boolean end local wordi_mt = {__index = WordInfo} -function WordInfo:new(funct: State, imm: boolean): WordInfo +function WordInfo:new(funct: function(State), imm: boolean): WordInfo return setmetatable({func = funct, immediate = imm} as WordInfo, wordi_mt) end