-#FLOOD_WITH_RANDOM {
+@FLOOD_WITH_RANDOM() {
$m6 = (256 * 256 * 256) - 1
$m7 = !GET_WIDTH()
$m8 = !GET_HEIGHT()
}
//change 1, 2, 3 4, 7, 8
-#TAKE_AVERAGE {
+@TAKE_AVERAGE() {
//Red, Green and Blue Sum
$m1 = 0
$m2 = 0
//Assumes 128 by 128 board
-#BOARD_WIDTH { !GET_WIDTH() }
-#BOARD_HEIGHT { !GET_HEIGHT() }
+@BOARD_WIDTH() { !GET_WIDTH() }
+@BOARD_HEIGHT() { !GET_HEIGHT() }
-#CELL_ALIVE { 255 }
-#CELL_DEAD { 0 }
+@CELL_ALIVE() { 255 }
+@CELL_DEAD() { 0 }
// Set up initial board
$y = 0
$y = $y + 1
}
-#UPDATE_CURRENT {
+@UPDATE_CURRENT() {
//Neighbor count
$m1 = 0
$x = $x - 1
$y = $y - 1
- $m2 = !get_a() == !CELL_ALIVE()
- if $m2 {
- if ($m1 < 2) + ($m1 > 3) {
+ if !get_a() == !CELL_ALIVE() {
+ if ($m1 < 2) | ($m1 > 3) {
!set_r(!CELL_DEAD())
}
} else {
}
}
-#COPY_BOARD {
+@COPY_BOARD() {
$y = 0
while $y < !BOARD_HEIGHT() {
$x = 0
if $m7 <= 0 {
$m7 = 1
- $y = 0
- while $y < !BOARD_HEIGHT() {
- $x = 0
- while $x < !BOARD_WIDTH() {
- !COPY_BOARD()
- $x = $x + 1
- }
- $y = $y + 1
- }
+ !COPY_BOARD()
$y = 0
while $y < !BOARD_HEIGHT() {
$y = $y + 1
}
}
-}
\ No newline at end of file
+}
+
+(5 > 4) & (7 > 10)
\ No newline at end of file
-#push_pos {
+@push_pos() {
$m1 = ($y * 256 * 256) + $x
!step_to_linear(0)
$y = $m1 / (256 * 256)
}
-#pop_pos {
+@pop_pos() {
!step_to_linear(0)
!step_to_linear(!get_col())
$m1 = !get_col()
$y = $m1 / (256 * 256)
}
-#get_stack_height {
+@get_stack_height() {
!push_pos()
!step_to_linear(0)
$m2 = !get_col() - 1
while $y < !get_height() {
$x = 0
while $x < !get_width() {
- !set_col(50)
+ !set_col(255)
$x = $x + 1
}
$y = $y + 1
$x = 1
$y = 21
!push_pos()
-!set_col(255)
+!set_col(50)
while !get_stack_height() > 0 {
!pop_pos()
!push_pos()
$m1 = 0
$y = $y - 2
- $m1 = $m1 + if !get_col() == 50 { 1 } else { 0 }
+ $m1 = $m1 + if !get_col() == 255 { 1 } else { 0 }
$y = $y + 2
$x = $x - 2
- $m1 = $m1 + if !get_col() == 50 { 1 } else { 0 }
+ $m1 = $m1 + if !get_col() == 255 { 1 } else { 0 }
$x = $x + 4
- $m1 = $m1 + if !get_col() == 50 { 1 } else { 0 }
+ $m1 = $m1 + if !get_col() == 255 { 1 } else { 0 }
$x = $x - 2
$y = $y + 2
- $m1 = $m1 + if !get_col() == 50 { 1 } else { 0 }
+ $m1 = $m1 + if !get_col() == 255 { 1 } else { 0 }
$y = $y - 2
if $m1 {
// dx and dy
$m5 = $m6 = 0
- if $m7 == 0 {
- $m6 = -2
- }
- if $m7 == 1 {
- $m5 = 2
- }
- if $m7 == 2 {
- $m6 = 2
- }
- if $m7 == 3 {
- $m5 = -2
- }
+ if $m7 == 0 { $m6 = -2 }
+ if $m7 == 1 { $m5 = 2 }
+ if $m7 == 2 { $m6 = 2 }
+ if $m7 == 3 { $m5 = -2 }
if !in_bounds($x + $m5, $y + $m6) {
!push_pos()
!push_pos()
$x = $x + $m5
$y = $y + $m6
- if !get_col() == 50 {
- !set_col(255)
+ if !get_col() == 255 {
+ !set_col(50)
!pop_pos()
$x = $x + $m5 / 2
$y = $y + $m6 / 2
- !set_col(255)
+ !set_col(50)
!pop_pos()
$x = $x + $m5
$y = $y + $m6
--- /dev/null
+@test_func($p1, $p2) {
+ $p1 + $p2
+}
+
+@move_to($p1, $p2) {
+ $x = $p1
+ $y = $p2
+}
+
+$p1 = 100
+
+$m1 = 0
+@rec($p1) {
+ $m1 = $m1 + 1
+ if $p1 <= 1 {
+ 1
+ } else {
+ !test_func($p1, !rec($p1 - 1))
+ }
+}
+
+!say(!rec($p1), $m1)
+!say($p1)
import ../board/board
import ../gfx/window
+const MAX_STACK_HEIGHT = 400
+
type
+ PContext = object
+ p_1, p_2, p_3, p_4: LightInt
+
+ PStack = ref object
+ stack: ref array[MAX_STACK_HEIGHT, PContext]
+ size: int
+
LightWorker = ref object
- var_1*, var_2*, var_3*, var_4*: LightInt
- var_5*, var_6*, var_7*, var_8*: LightInt
+ mem_1*, mem_2*, mem_3*, mem_4*: LightInt
+ mem_5*, mem_6*, mem_7*, mem_8*: LightInt
pos_x*, pos_y*: LightInt
+ param_stack: PStack
ExecFuncs* = TableRef[string, proc(ec: ExecutionContext, args: openarray[LightInt]): LightInt]
+ DefFuncs = ref object
+ params: seq[LightVariable]
+ body: seq[LightExpr]
+
ExecutionContext* = ref object
worker*: LightWorker
builtin_functions: ExecFuncs
- defined_functions: TableRef[string, seq[LightExpr]]
+ defined_functions: TableRef[string, DefFuncs]
running: bool
break_flag: bool
+proc Top(pstack: PStack): var PContext =
+ pstack.stack[pstack.size - 1]
+
+proc Push(pstack: var PStack, ctx: PContext) =
+ pstack.stack[pstack.size] = ctx
+ pstack.size += 1
+
+proc Pop(pstack: var PStack): PContext =
+ pstack.size -= 1
+
proc MakeEmptyWorker(): LightWorker =
- LightWorker()
+ let worker = LightWorker()
+ let param_ctx = new(array[MAX_STACK_HEIGHT, PContext])
+ worker.param_stack = PStack(
+ stack: param_ctx,
+ size: 1
+ )
+ worker
proc MakeExecutionContext*(funcs: ExecFuncs): ExecutionContext =
let worker = MakeEmptyWorker()
- let defined_functions = newTable[string, seq[LightExpr]]()
+ let defined_functions = newTable[string, DefFuncs]()
ExecutionContext(
worker: worker,
builtin_functions: funcs,
func GetVar(worker: LightWorker, variable: LightVariable): LightInt =
case variable:
- of var1: worker.var_1
- of var2: worker.var_2
- of var3: worker.var_3
- of var4: worker.var_4
- of var5: worker.var_5
- of var6: worker.var_6
- of var7: worker.var_7
- of var8: worker.var_8
- of varX: worker.pos_x
- of varY: worker.pos_y
+ of var_m1: worker.mem_1
+ of var_m2: worker.mem_2
+ of var_m3: worker.mem_3
+ of var_m4: worker.mem_4
+ of var_m5: worker.mem_5
+ of var_m6: worker.mem_6
+ of var_m7: worker.mem_7
+ of var_m8: worker.mem_8
+ of var_x: worker.pos_x
+ of var_y: worker.pos_y
+ of var_p1: worker.param_stack.Top().p_1
+ of var_p2: worker.param_stack.Top().p_2
+ of var_p3: worker.param_stack.Top().p_3
+ of var_p4: worker.param_stack.Top().p_4
func SetVar(worker: LightWorker, variable: LightVariable, value: LightInt): LightInt =
case variable:
- of var1: worker.var_1 = value
- of var2: worker.var_2 = value
- of var3: worker.var_3 = value
- of var4: worker.var_4 = value
- of var5: worker.var_5 = value
- of var6: worker.var_6 = value
- of var7: worker.var_7 = value
- of var8: worker.var_8 = value
- of varX: worker.pos_X = value
- of varY: worker.pos_Y = value
+ of var_m1: worker.mem_1 = value
+ of var_m2: worker.mem_2 = value
+ of var_m3: worker.mem_3 = value
+ of var_m4: worker.mem_4 = value
+ of var_m5: worker.mem_5 = value
+ of var_m6: worker.mem_6 = value
+ of var_m7: worker.mem_7 = value
+ of var_m8: worker.mem_8 = value
+ of var_x: worker.pos_x = value
+ of var_y: worker.pos_y = value
+ of var_p1: worker.param_stack.Top().p_1 = value
+ of var_p2: worker.param_stack.Top().p_2 = value
+ of var_p3: worker.param_stack.Top().p_3 = value
+ of var_p4: worker.param_stack.Top().p_4 = value
value
ec.builtin_functions[exp.func_name](ec, args)
elif ec.defined_functions.hasKey(exp.func_name):
- ExecuteLines(ec, ec.defined_functions[exp.func_name])
+ var args = newSeq[LightInt]()
+ for param in exp.params:
+ args.add(EvalExpr(ec, param))
+
+ var ind: int = 0
+ var params: PContext
+
+ for par in ec.defined_functions[exp.func_name].params:
+ if ind >= args.len:
+ raise newException(ValueError, "Too few parameters to function call")
+
+ if par == var_p1: params.p_1 = args[ind]
+ elif par == var_p2: params.p_2 = args[ind]
+ elif par == var_p3: params.p_3 = args[ind]
+ elif par == var_p4: params.p_4 = args[ind]
+
+ ind += 1
+
+ ec.worker.param_stack.Push(params)
+ let ret = ExecuteLines(ec, ec.defined_functions[exp.func_name].body)
+ discard ec.worker.param_stack.Pop()
+ ret
else:
raise newException(ValueError, "Cannot call undefined function: " & exp.func_name)
raise newException(ValueError, "Cannot redefine function: " & exp.def_func_name)
else:
- ec.defined_functions[exp.def_func_name] = exp.func_body
+ ec.defined_functions[exp.def_func_name] = DefFuncs(
+ params: exp.param_vars,
+ body: exp.func_body
+ )
0
else:
0
if varString == "":
raise newException(IOError, "Expected variable name")
else:
- if varString == "m1": varName = var1
- elif varString == "m2": varName = var2
- elif varString == "m3": varName = var3
- elif varString == "m4": varName = var4
- elif varString == "m5": varName = var5
- elif varString == "m6": varName = var6
- elif varString == "m7": varName = var7
- elif varString == "m8": varName = var8
- elif varString == "x": varName = varX
- elif varString == "y": varName = varY
+ if varString == "m1": varName = var_m1
+ elif varString == "m2": varName = var_m2
+ elif varString == "m3": varName = var_m3
+ elif varString == "m4": varName = var_m4
+ elif varString == "m5": varName = var_m5
+ elif varString == "m6": varName = var_m6
+ elif varString == "m7": varName = var_m7
+ elif varString == "m8": varName = var_m8
+ elif varString == "p1": varName = var_p1
+ elif varString == "p2": varName = var_p2
+ elif varString == "p3": varName = var_p3
+ elif varString == "p4": varName = var_p4
+ elif varString == "x": varName = var_x
+ elif varString == "y": varName = var_y
else:
raise newException(IOError, "Invalid variable name.")
let funcName = token[1..^1].toLowerAscii
yield LightToken(kind: ltFunc, func_name: funcName)
- elif token.startsWith('#'):
+ elif token.startsWith('@'):
let funcName = token[1..^1].toLowerAscii
yield LightToken(kind: ltFuncDef, func_name: funcName)
elif token == "=":
yield LightToken(kind: ltEq)
- elif token.startsWith("-") and token != "-":
- var value: int
- discard parseutils.parseInt(token, value)
-
- yield LightToken(kind: ltNum, value: value.LightInt)
-
- elif token.isDigit:
+ elif (token.startsWith("-") and token != "-") or token.isDigit:
var value: int
discard parseutils.parseInt(token, value)
yield LightToken(kind: ltOp, operation: loDiv)
of "%":
yield LightToken(kind: ltOp, operation: loMod)
+ of "&":
+ yield LightToken(kind: ltOp, operation: loBitAnd)
+ of "|":
+ yield LightToken(kind: ltOp, operation: loBitOr)
+ of "^":
+ yield LightToken(kind: ltOp, operation: loBitXor)
of "<":
yield LightToken(kind: ltOp, operation: loLt)
of "<=":
)
elif curr.kind == ltFuncDef:
+ if tokens.Current.kind != ltLeftParen:
+ raise newException(ValueError, "Expected parameter list before function definition")
+
+ tokens.Step()
+ let params = ParseBlock(tokens, ltParamDelim, ltRightParen)
+ var param_list = newSeq[LightVariable]()
+ for param in params:
+ if param.kind != leVar:
+ raise newException(ValueError, "Only parameter variables in function defintion parameter list")
+ if (param.variable < var_p1) or (param.variable > var_p4):
+ raise newException(ValueError, "Only parameter variables in function defintion parameter list")
+ else:
+ param_list.add(param.variable)
+
+ # Allows for next line function body
+ if tokens.Current.kind == ltExprDelim:
+ tokens.Step()
+
if tokens.Current.kind != ltBlockStart:
- raise newException(ValueError, "Expected block start after function definition")
-
+ raise newException(ValueError, "Expected function body")
+
tokens.Step()
let body = ParseBlock(tokens, ltExprDelim, ltBlockEnd)
return LightExpr(
kind: leFuncDef,
def_func_name: curr.func_name,
+ param_vars: param_list,
func_body: body
)
params*: seq[LightExpr]
of leFuncDef:
def_func_name*: string
+ param_vars*: seq[LightVariable]
func_body*: seq[LightExpr]
else:
discard
of leWhile: "while [" & printExpr(exp.condition, 0) & "] {\n" & multiline(exp.body, ind + 1) & "\n" & ts & "}"
of leBreak: "break"
of leFuncCall: "funcCall[" & exp.func_name & ", " & $exp.params & "]"
- of leFuncDef: "funcDef[" & exp.def_func_name & "] {\n" & multiline(exp.func_body, ind + 1) & "\n" & ts & "}"
+ of leFuncDef: "funcDef[" & exp.def_func_name & "] (" & $exp.param_vars & ") {\n" & multiline(exp.func_body, ind + 1) & "\n" & ts & "}"
of leNull: "NullExpr[]"
else: "UNDEFINED[]"
)
else:
discard
-func `$`*(variable: LightVariable): string =
- case variable:
- of var1: "MEM_1"
- of var2: "MEM_2"
- of var3: "MEM_3"
- of var4: "MEM_4"
- of var5: "MEM_5"
- of var6: "MEM_6"
- of var7: "MEM_7"
- of var8: "MEM_8"
- of varX: "POS_X"
- of varY: "POS_Y"
-
proc `$`*(token: LightToken): string =
return
case token.kind:
type
LightVariable* = enum
- var1 = 0, var2 = 1, var3 = 2, var4 = 3,
- var5 = 4, var6 = 5, var7 = 6, var8 = 7,
- varX = 8, varY = 9
+ var_m1, var_m2, var_m3, var_m4,
+ var_m5, var_m6, var_m7, var_m8,
+ var_p1, var_p2, var_p3, var_p4,
+ var_x, var_y
LightOperation* = enum
loAdd, loSub, loMul, loDiv, loMod,
+ loBitAnd, loBitOr, loBitXor,
loGt, loGte, loLt, loLte, loEq, loNeq
LightInt* = int32
+
+func `$`*(variable: LightVariable): string =
+ case variable:
+ of var_m1: "MEM_1"
+ of var_m2: "MEM_2"
+ of var_m3: "MEM_3"
+ of var_m4: "MEM_4"
+ of var_m5: "MEM_5"
+ of var_m6: "MEM_6"
+ of var_m7: "MEM_7"
+ of var_m8: "MEM_8"
+ of var_p1: "PRM_1"
+ of var_p2: "PRM_2"
+ of var_p3: "PRM_3"
+ of var_p4: "PRM_4"
+ of var_x: "POS_X"
+ of var_y: "POS_Y"
of loMul: left * right
of loDiv: left div right
of loMod: left mod right
+ of loBitAnd: left and right
+ of loBitOr: left or right
+ of loBitXor: left xor right
of loGt:
if left > right: 1
else: 0