From ecdf648d962866628a7547edf0be712add50ab8b Mon Sep 17 00:00:00 2001 From: Starfflame Date: Thu, 13 May 2021 05:54:06 -0500 Subject: [PATCH] Expand core words dictionary --- CoreHelpers.tl | 7 +++ CoreWords.tl | 114 +++++++++++++++++++++++++++++++++++++++++++++- DataStructures.tl | 5 +- 3 files changed, 122 insertions(+), 4 deletions(-) diff --git a/CoreHelpers.tl b/CoreHelpers.tl index 523e51d..56001ce 100644 --- a/CoreHelpers.tl +++ b/CoreHelpers.tl @@ -3,6 +3,13 @@ local Dictionary, Stack, WordInfo, State = ds.Dictionary, ds.Stack, ds.WordInfo, local CoreHelpers = {} +function CoreHelpers.defineWord(dict: Dictionary, str: string, func: function(State, ...: any): any..., imm: boolean) + local info = WordInfo:new(func, imm) + dict:define(str, info) +end + + + function CoreHelpers.areNumbers(a: any, b: any): boolean return a is number and b is number end diff --git a/CoreWords.tl b/CoreWords.tl index fb87e8c..b0a1c04 100644 --- a/CoreWords.tl +++ b/CoreWords.tl @@ -4,7 +4,7 @@ local helpers = require("CoreHelpers") local areNumbers, getActiveDataStack, isNumber, isWhitespace= helpers.areNumbers, helpers.getActiveDataStack, helpers.isNumber, helpers.isWhitespace local skipWhitespace, parseToken = helpers.skipWhitespace, helpers.parseToken local popTwoOperands = helpers.popTwoOperands - +local defineWord = helpers.defineWord -- Mathematical operations local function add(state: State) local a, b = popTwoOperands(state) @@ -42,12 +42,99 @@ local function div(state: State) error("invalid operands for div operation!") end end + +local function dup(state: State) + local stack = getActiveDataStack(state) + local top = stack:pop() + stack:push(top) + stack:push(top) +end +local function swap(state: State) + local stack = getActiveDataStack(state) + local a, b = popTwoOperands(state) + stack:push(b) + stack:push(a) +end +local function rot(state: State) + local stack = getActiveDataStack(state) + local c, b, a= stack:pop(), stack:pop(), stack:pop() + stack:push(b) + stack:push(c) + stack:push(a) +end +local function drop(state: State) + local stack = getActiveDataStack(state) + stack:pop() +end +local function over(state: State) + local stack = getActiveDataStack(state) + local b, a = stack:pop(), stack:pop() + stack:push(a) + stack:push(b) + stack:push(a) +end -- I/O operations local function dot(state: State) local out = state.activeDataStack:pop() print(out) - end +local function twoDup(state: State) + over(state) + over(state) +end +local function twoSwap(state: State) + local stack = getActiveDataStack(state) + local d, c, b, a = stack:pop(), stack:pop(), stack:pop(), stack:pop() + stack:push(c) + stack:push(d) + stack:push(a) + stack:push(b) +end + + +local function twoOver(state: State) + local stack = getActiveDataStack(state) + local d, c, b, a = stack:pop(), stack:pop(), stack:pop(), stack:pop() + stack:push(a) + stack:push(b) + stack:push(c) + stack:push(d) + stack:push(a) + stack:push(b) +end +local function nip(state: State) + local stack = getActiveDataStack(state) + local b, _ = stack:pop(), stack:pop() + stack:push(b) +end +local function tuck(state: State) + swap(state) + over(state) +end +local function roll(state: State) + local stack = getActiveDataStack(state) + local u = stack:pop() + local bufferStack = Stack:new() + if u is number then + local v = u as number + while(v > 0) do + local item = stack:pop() + bufferStack:push(item) + v = v - 1 + end + local newTop = stack:pop() + local x = (u as number) + while(x > 0) do + local item = bufferStack:pop() + stack:push(item) + x = x - 1 + end + stack:push(newTop) + else + error("u is not a number") + end +end + local CoreWords = Dictionary:new() local addInfo = WordInfo:new(add, false) @@ -55,11 +142,34 @@ local subInfo = WordInfo:new(sub, false) local mulInfo = WordInfo:new(mul, false) local divInfo = WordInfo:new(div, false) local dotInfo = WordInfo:new(dot, false) +local dupInfo = WordInfo:new(dup, false) +local swapInfo = WordInfo:new(swap, false) +local rotInfo = WordInfo:new(rot, false) +local dropInfo = WordInfo:new(drop, false) +local overInfo = WordInfo:new(over, false) +local twoDupInfo = WordInfo:new(twoDup, false) +local twoSwapInfo = WordInfo:new(twoSwap, false) +local twoOverInfo = WordInfo:new(twoOver, false) +local nipInfo = WordInfo:new(nip, false) + +defineWord(CoreWords, "TUCK", tuck, false) +defineWord(CoreWords, "ROLL", roll, false) + CoreWords:define("+", addInfo) CoreWords:define("-", subInfo) CoreWords:define("*", mulInfo) CoreWords:define("/", divInfo) CoreWords:define(".", dotInfo) + +CoreWords:define("DUP", dupInfo) +CoreWords:define("SWAP", swapInfo) +CoreWords:define("ROT", rotInfo) +CoreWords:define("DROP", dropInfo) +CoreWords:define("OVER", overInfo) +CoreWords:define("2DUP", twoDupInfo) +CoreWords:define("2SWAP", twoSwapInfo) +CoreWords:define("2OVER", twoOverInfo) +CoreWords:define("NIP", nipInfo) return CoreWords diff --git a/DataStructures.tl b/DataStructures.tl index 56ac24e..7ee3e54 100644 --- a/DataStructures.tl +++ b/DataStructures.tl @@ -31,13 +31,14 @@ local type DataStructures = record interrupts: {function(State)} activeInputStream: InputStream dictionaries: {Dictionary} - + state: boolean new: function(State): State addDataStack: function(State, Stack) changeCompilerStack: function(State, Stack) changeActiveDataStack: function(State, number) - end + end + end local Stack, State, Dictionary, WordInfo = DataStructures.Stack, DataStructures.State, DataStructures.Dictionary, DataStructures.WordInfo