Move helper functions for the CoreWords dictionary into its own module.
This commit is contained in:
parent
fe6bc4f8cb
commit
e5090f532e
|
@ -0,0 +1,56 @@
|
||||||
|
local ds = require("DataStructures")
|
||||||
|
local Dictionary, Stack, WordInfo, State = ds.Dictionary, ds.Stack, ds.WordInfo, ds.State
|
||||||
|
|
||||||
|
local CoreHelpers = {}
|
||||||
|
|
||||||
|
function CoreHelpers.areNumbers(a: any, b: any): boolean
|
||||||
|
return a is number and b is number
|
||||||
|
end
|
||||||
|
|
||||||
|
function CoreHelpers.getActiveDataStack(state: State): 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: State)
|
||||||
|
local chr = state.activeInputStream:readCurrentCharacter()
|
||||||
|
while (CoreHelpers.isWhitespace(chr)) do
|
||||||
|
chr = state.activeInputStream:advanceOffset()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function CoreHelpers.popTwoOperands(state: State): 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: State): string
|
||||||
|
local chr = state.activeInputStream:readCurrentCharacter()
|
||||||
|
local token = ""
|
||||||
|
while(not CoreHelpers.isWhitespace(chr)) do
|
||||||
|
token = token..chr
|
||||||
|
chr = state.activeInputStream:advanceOffset()
|
||||||
|
end
|
||||||
|
return token
|
||||||
|
end
|
||||||
|
|
||||||
|
return CoreHelpers
|
||||||
|
|
80
CoreWords.tl
80
CoreWords.tl
|
@ -1,45 +1,14 @@
|
||||||
local ds = require("DataStructures")
|
local ds = require("DataStructures")
|
||||||
local Dictionary, Stack, WordInfo, State = ds.Dictionary, ds.Stack, ds.WordInfo, ds.State
|
local Dictionary, Stack, WordInfo, State = ds.Dictionary, ds.Stack, ds.WordInfo, ds.State
|
||||||
|
local helpers = require("CoreHelpers")
|
||||||
|
local areNumbers, getActiveDataStack, isNumber, isWhitespace= helpers.areNumbers, helpers.getActiveDataStack, helpers.isNumber, helpers.isWhitespace
|
||||||
-- helper functions
|
local skipWhitespace, parseToken = helpers.skipWhitespace, helpers.parseToken
|
||||||
local function areNumbers(state: State, a: any, b: any): boolean
|
local popTwoOperands = helpers.popTwoOperands
|
||||||
return a is number and b is number
|
|
||||||
end
|
|
||||||
|
|
||||||
local function getActiveDataStack(state: State): Stack
|
|
||||||
return state.activeDataStack
|
|
||||||
end
|
|
||||||
|
|
||||||
local function isNumber(state: State, token: string): boolean
|
|
||||||
if tonumber(token) ~= nil then
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function isWhitespace(state: State, chr: string): boolean
|
|
||||||
return (chr == " " or
|
|
||||||
chr == "\t" or
|
|
||||||
chr == "\r" or
|
|
||||||
chr == "\n" or
|
|
||||||
chr == "\v" or
|
|
||||||
chr == "\f")
|
|
||||||
end
|
|
||||||
|
|
||||||
local 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
|
-- Mathematical operations
|
||||||
local function add(state: State)
|
local function add(state: State)
|
||||||
local a, b = popTwoOperands(state)
|
local a, b = popTwoOperands(state)
|
||||||
if areNumbers(state, 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(state):push(c)
|
||||||
else
|
else
|
||||||
|
@ -48,7 +17,7 @@ local function add(state: State)
|
||||||
end
|
end
|
||||||
local function sub(state: State)
|
local function sub(state: State)
|
||||||
local a, b = popTwoOperands(state)
|
local a, b = popTwoOperands(state)
|
||||||
if areNumbers(state, 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(state):push(c)
|
||||||
else
|
else
|
||||||
|
@ -57,7 +26,7 @@ local function sub(state: State)
|
||||||
end
|
end
|
||||||
local function mul(state: State)
|
local function mul(state: State)
|
||||||
local a, b = popTwoOperands(state)
|
local a, b = popTwoOperands(state)
|
||||||
if areNumbers(state, 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(state):push(c)
|
||||||
else
|
else
|
||||||
|
@ -66,7 +35,7 @@ local function mul(state: State)
|
||||||
end
|
end
|
||||||
local function div(state: State)
|
local function div(state: State)
|
||||||
local a, b = popTwoOperands(state)
|
local a, b = popTwoOperands(state)
|
||||||
if areNumbers(state, 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(state):push(c)
|
||||||
else
|
else
|
||||||
|
@ -80,50 +49,17 @@ local function dot(state: State)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function skipWhitespace(state: State)
|
|
||||||
local chr = state.activeInputStream:readCurrentCharacter()
|
|
||||||
while (isWhitespace(state, chr)) do
|
|
||||||
chr = state.activeInputStream:advanceOffset()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function parseToken(state: State): string
|
|
||||||
local chr = state.activeInputStream:readCurrentCharacter()
|
|
||||||
local token = ""
|
|
||||||
while(not isWhitespace(state, chr)) do
|
|
||||||
token = token..chr
|
|
||||||
chr = state.activeInputStream:advanceOffset()
|
|
||||||
end
|
|
||||||
return token
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local CoreWords = Dictionary:new()
|
local CoreWords = Dictionary:new()
|
||||||
local addInfo = WordInfo:new(add, false)
|
local addInfo = WordInfo:new(add, false)
|
||||||
local subInfo = WordInfo:new(sub, false)
|
local subInfo = WordInfo:new(sub, false)
|
||||||
local mulInfo = WordInfo:new(mul, false)
|
local mulInfo = WordInfo:new(mul, false)
|
||||||
local divInfo = WordInfo:new(div, false)
|
local divInfo = WordInfo:new(div, false)
|
||||||
local dotInfo = WordInfo:new(dot, false)
|
local dotInfo = WordInfo:new(dot, false)
|
||||||
local getActiveDataStackInfo = WordInfo:new(getActiveDataStack, true)
|
|
||||||
local areNumbersInfo = WordInfo:new(areNumbers, false)
|
|
||||||
local isNumberInfo = WordInfo:new(isNumber, false)
|
|
||||||
local isWhitespaceInfo = WordInfo:new(isWhitespace, false)
|
|
||||||
local popTwoOperandsInfo = WordInfo:new(popTwoOperands, false)
|
|
||||||
local parseTokenInfo = WordInfo:new(parseToken, true)
|
|
||||||
local skipWhitespaceInfo = WordInfo:new(skipWhitespace, true)
|
|
||||||
CoreWords:define("+", addInfo)
|
CoreWords:define("+", addInfo)
|
||||||
CoreWords:define("-", subInfo)
|
CoreWords:define("-", subInfo)
|
||||||
CoreWords:define("*", mulInfo)
|
CoreWords:define("*", mulInfo)
|
||||||
CoreWords:define("/", divInfo)
|
CoreWords:define("/", divInfo)
|
||||||
CoreWords:define(".", dotInfo)
|
CoreWords:define(".", dotInfo)
|
||||||
CoreWords:define("GetActiveData", getActiveDataStackInfo)
|
|
||||||
CoreWords:define("areNumbers", areNumbersInfo)
|
|
||||||
CoreWords:define("isNumber", isNumberInfo)
|
|
||||||
CoreWords:define("isWhitespace", isWhitespaceInfo)
|
|
||||||
CoreWords:define("popTwo", popTwoOperandsInfo)
|
|
||||||
CoreWords:define("parseToken", parseTokenInfo)
|
|
||||||
CoreWords:define("skipWhitespace", skipWhitespaceInfo)
|
|
||||||
return CoreWords
|
return CoreWords
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,8 @@ local CoreWords = require("CoreWords")
|
||||||
local ds = require("DataStructures")
|
local ds = require("DataStructures")
|
||||||
local istream = require("InputStream")
|
local istream = require("InputStream")
|
||||||
local Stack, Dictionary, WordInfo, State = ds.Stack, ds.Dictionary, ds.WordInfo, ds.State
|
local Stack, Dictionary, WordInfo, State = ds.Stack, ds.Dictionary, ds.WordInfo, ds.State
|
||||||
|
local helpers = require("CoreHelpers")
|
||||||
|
local isNumber, skipWhitespace, parseToken = helpers.isNumber, helpers.skipWhitespace, helpers.parseToken
|
||||||
local machineState = State:new()
|
local machineState = State:new()
|
||||||
|
|
||||||
function standardInputRefill(): string
|
function standardInputRefill(): string
|
||||||
|
@ -16,18 +17,11 @@ machineState.activeInputStream = standardInputStream
|
||||||
machineState.activeDataStack = Stack:new()
|
machineState.activeDataStack = Stack:new()
|
||||||
table.insert(machineState.dictionaries, CoreWords)
|
table.insert(machineState.dictionaries, CoreWords)
|
||||||
|
|
||||||
local getActiveDataStacks = (CoreWords:lookup("GetActiveData") as WordInfo).func
|
|
||||||
local areNumbers = (CoreWords:lookup("areNumbers") as WordInfo).func
|
|
||||||
local isNumber = (CoreWords:lookup("isNumber") as WordInfo).func
|
|
||||||
local isWhitespace = (CoreWords:lookup("isWhitespace") as WordInfo).func
|
|
||||||
local popTwoOperands = (CoreWords:lookup("popTwo") as WordInfo).func
|
|
||||||
local skipWhitespace = (CoreWords:lookup("skipWhitespace") as WordInfo).func
|
|
||||||
local parseToken = (CoreWords:lookup("parseToken") as WordInfo).func
|
|
||||||
|
|
||||||
while(true) do
|
while(true) do
|
||||||
skipWhitespace(machineState)
|
skipWhitespace(machineState)
|
||||||
local token: string = parseToken(machineState)
|
local token: string = parseToken(machineState)
|
||||||
if isNumber(machineState, token) then
|
if isNumber(token) then
|
||||||
machineState.activeDataStack:push(tonumber(token))
|
machineState.activeDataStack:push(tonumber(token))
|
||||||
else
|
else
|
||||||
for i, dictionary in ipairs(machineState.dictionaries) do
|
for i, dictionary in ipairs(machineState.dictionaries) do
|
||||||
|
|
Loading…
Reference in New Issue