local ds = require("DataStructures") local Dictionary, Stack, WordInfo, Environment = ds.Dictionary, ds.Stack, ds.WordInfo, ds.Environment local Pointer = ds.Pointer local InputStream = require("InputStream") local CoreHelpers = {} function CoreHelpers.defineWord(dict: Dictionary, str: string, func: function(Environment, ...: any): any..., imm: boolean) local info = WordInfo:new(func, imm) dict:define(str, info) end function CoreHelpers.standardInputRefill(): string local input = io.read().."\n" return input end function CoreHelpers._oneReadRefill(str: string): function(): string local alreadyRead: boolean = false return function(): string if not alreadyRead then alreadyRead = true return str else return "" end end end function CoreHelpers._fileRefill(fname: string): function(): string local f = assert(io.open(fname, "r")) return function(): string local chunk = f:read(2^13) if not chunk then chunk = "" end return chunk end end function CoreHelpers.fileStream(fname: string): InputStream local istream = InputStream:new(CoreHelpers._fileRefill(fname)) return istream end function CoreHelpers.oneReadInputStream(str: string): InputStream local iStream = InputStream:new(CoreHelpers._oneReadRefill(str)) return iStream end function CoreHelpers.areNumbers(a: any, b: any): boolean return a is number and b is number end function CoreHelpers.getActiveDataStack(state: Environment): Stack return state.activeDataStack end function CoreHelpers.isNumber(token: string): boolean if tonumber(token) ~= nil then return true else return false end end function CoreHelpers.isWhitespace(chr: string): boolean return (chr == " " or chr == "\t" or chr == "\r" or chr == "\n" or chr == "\v" or chr == "\f") end function CoreHelpers.skipWhitespace(state: Environment) local chr = state.activeInputStream:curr() while (CoreHelpers.isWhitespace(chr)) do chr = state.activeInputStream:next() end end function CoreHelpers.popTwoOperands(state: Environment): any, any local stack = CoreHelpers.getActiveDataStack(state) local b: any = stack:pop() local a: any = stack:pop() return a, b end function CoreHelpers.parseToken(state: Environment): string local chr = "" local token = "" while(not CoreHelpers.isWhitespace(chr)) do token = token..chr chr = state.activeInputStream:next() end return token end function CoreHelpers.reset(env: Environment) env.instructionPointer.index = 0 -- will get incremented after this instruction end function CoreHelpers.ret(env: Environment) local retAddr = env.returnStack:pop() as Pointer env.instructionPointer = retAddr end function CoreHelpers.makeCall(body: {function(Environment)}): function(Environment) return function(e: Environment) e.returnStack:push(e.instructionPointer) e.instructionPointer = Pointer:new(body, 0) end end return CoreHelpers