requires "glfw"
task run, "Run project":
- exec("nimble build")
+ exec("nimble build -d:release")
exec("./christmas_proj")
\ No newline at end of file
--- /dev/null
+$mem_2 = 0
+$mem_3 = 10000
+
+while 1 {
+ $pos_x = 0
+ $pos_y = 0
+ while $pos_y < 256 {
+ $mem_1 = 20 * $pos_x + $mem_2 / 4
+ $mem_1 = $mem_1 + $pos_y * $pos_x * 5
+ !set_col($mem_1)
+ !step_linear(1)
+ }
+ $mem_2 = $mem_2 + 1
+ !render()
+
+ $mem_3 = $mem_3 - 1
+ if $mem_3 <= 0 {
+ !halt()
+ }
+}
+
--- /dev/null
+$pos_x = 0
+$pos_y = 10
+$mem_8 = 1
+
+#move_diag {
+ $pos_x = $pos_x + $mem_8
+ $pos_y = $pos_y + $mem_8
+}
+
+#swap_xy {
+ $mem_1 = $pos_x
+ $pos_x = $pos_y
+ $pos_y = $mem_1
+}
+
+$mem_3 = 100
+while $pos_x <= 255 {
+ $mem_3 = $mem_3 + 4
+ if $mem_3 >= 256 {
+ $mem_3 = $mem_3 - 156
+ }
+
+ !set_col($pos_x, $pos_y, $mem_3)
+ !move_diag()
+ !swap_xy()
+ !render()
+}
+
+$pos_x = 240
+$pos_y = 255
+$mem_8 = 0 - 1
+
+while $pos_x >= 0 {
+ !set_col($pos_x, $pos_y, 255)
+ !move_diag()
+ !render()
+}
+
+!say($pos_x)
+$mem_2 = if $pos_x < 0 {
+ 1000
+}
+!say($mem_2)
-$MEM_1 = 0
-$MEM_2 = 1
+$mem_1 = 0
+$mem_2 = 1
-WHILE $MEM_2 < 100000 DO
- $MEM_3 = $MEM_1 + $MEM_2
- $MEM_1 = $MEM_2
- $MEM_2 = $MEM_3
- !PRINT($MEM_3, 3 + $MEM_7)
-END
+//Dummy function that doesn't do much
+#test {
+ !say($mem_1 + $mem_2)
+}
-IF !IN_BOUNDS($POS_X + 1, $POS_Y) THEN
- !SAY($MEM_8)
-END
+while $mem_2 < 100000 {
+ $mem_3 = $mem_1 + $mem_2
+ $mem_1 = $mem_2
+ $mem_2 = $mem_3
+ !say($mem_3, $mem_2, $mem_2 == $mem_3)
+}
-!REDRAW()
\ No newline at end of file
+if !in_bounds($pos_x + 1, $pos_y) {
+ !test()
+}
+
+!redraw()
\ No newline at end of file
import ../gfx/glutils
type
- LightBoard = ref object
+ LightBoard* = ref object
width: int
height: int
data: ref array[1024 * 1024, GLuint]
import os
-import sequtils
+import tables
import opengl
-import random
import glfw3 as glfw
import gfx/window as gfx_window
import gfx/glutils as glutils
-import lang/ast
-import lang/lexer as lexer
-import lang/parser as parser
-import lang/tokens
+import lang/types/types
+import lang/program
+import lang/executer
import board/board
if key == glfw.KEY_ESCAPE and action == glfw.PRESS:
glfw.SetWindowShouldClose(window, glfw.TRUE)
-proc main2() =
- let window = gfxWindow.NewWindow(800, 600, "ASDF")
- window.SetKeyCallback(key_down)
-
- let vertex_shader = glutils.CreateShader(glutils.stVertex, "./data/shaders/basic.vert")
- let fragment_shader = glutils.CreateShader(glutils.stFragment, "./data/shaders/basic.frag")
- let program = glutils.LinkProgram(vertex_shader, fragment_shader)
- glUseProgram(program)
-
- var vao: GLuint
- var temp_vao: GLuint
- glGenVertexArrays(1.GLsizei, vao.addr)
- glGenVertexArrays(1.GLsizei, temp_vao.addr)
-
- var vbo: GLuint
- var cbo: GLuint
- var ibo: GLuint
- glGenBuffers(1.GLsizei, vbo.addr)
- glGenBuffers(1.GLsizei, cbo.addr)
- glGenBuffers(1.GLsizei, ibo.addr)
-
- glBindVertexArray(vao)
- glEnableVertexAttribArray(0)
- glEnableVertexAttribArray(1)
-
- var vertex_data: array[6, GLfloat] = [
- 0'f32, 0'f32,
- 0'f32, 1'f32,
- 1'f32, 0'f32,
- ]
- glBindBuffer(GL_ARRAY_BUFFER, vbo)
- glBufferData(GL_ARRAY_BUFFER, vertex_data.sizeof, vertex_data.addr, GL_STATIC_DRAW)
- glVertexAttribPointer(0, 2, cGL_FLOAT, GL_FALSE, 8.GLsizei, nil)
-
- var color_data: array[8, GLfloat] = [
- 1'f32, 0'f32, 1'f32, 1'f32,
- 0'f32, 1'f32, 0'f32, 1'f32,
- ]
- glBindBuffer(GL_ARRAY_BUFFER, cbo)
- glBufferData(GL_ARRAY_BUFFER, color_data.sizeof, color_data.addr, GL_STATIC_DRAW)
- glVertexAttribDivisor(1, 1)
- glVertexAttribPointer(1, 4, cGL_FLOAT, GL_FALSE, 16.GLsizei, nil)
-
- var index_data: array[3, GLuint] = [
- 0.GLuint, 1.Gluint, 2.Gluint,
- ]
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data.sizeof, index_data.addr, GL_STATIC_DRAW)
-
- glBindVertexArray(0)
-
-
proc main() =
let window = gfxWindow.NewWindow(1200, 700, "ASDF")
window.SetKeyCallback(key_down)
- let source_code = readFile("data/progs/test.lgt")
- let tokens = toSeq(lexer.GenerateTokens(source_code))
- for exp in parser.ParseTokens(tokens):
- echo exp
+ let program = LoadProgram("./data/progs/fibcol.lgt")
- let board = CreateBoard(256, 256)
+ const board_width: int = 128
+ const board_height: int = 128
+ let board = CreateBoard(board_width, board_height)
board.InitRendering()
+ var funcs = newTable({
+ "say": (proc(ec: ExecutionContext, args: openarray[int32]): int32 {.closure.} =
+ echo $args
+ ),
+ "set_col": (proc(ec: ExecutionContext, args: openarray[int32]): int32 {.closure.} =
+ board.SetCol(ec.worker.pos_x.int, ec.worker.pos_y.int, args[0].GLuint)
+ ),
+ "step_linear": (proc(ec: ExecutionContext, args: openarray[int32]): int32 {.closure.} =
+ ec.worker.pos_x += args[0]
+ while ec.worker.pos_x >= board_width:
+ ec.worker.pos_x -= board_width.LightInt
+ ec.worker.pos_y += 1
+ while ec.worker.pos_x < 0:
+ ec.worker.pos_x += board_width.LightInt
+ ec.worker.pos_y -= 1
+ ),
+ "halt": (proc(ec: ExecutionContext, args: openarray[int32]): int32 {.closure.} =
+ ec.StopExecution()
+ ),
+ "render": (proc(ec: ExecutionContext, args: openarray[int32]): int32 {.closure.} =
+ glClearColor(0, 0, 0, 1)
+ glClear(GL_COLOR_BUFFER_BIT)
+
+ board.RebufferColors()
+ board.Render()
+
+ os.sleep(1)
+ window.Refresh()
+ if window.ShouldClose():
+ ec.StopExecution()
+ )
+ })
+
+ let ec = MakeExecutionContext(funcs)
+ discard ExecuteProgram(ec, program)
+
while not window.ShouldClose():
glClearColor(0, 0, 0, 1)
glClear(GL_COLOR_BUFFER_BIT)
-
- board.SetCol(random.rand(256), random.rand(256), random.rand(0xffffff).GLuint)
board.RebufferColors()
board.Render()
import opengl
type
- Window* = object
+ Window* = ref object
window: glfw.Window
width, height: cint
title: cstring
+++ /dev/null
-import ./types
-import ./tokens
-
-type
- LightExprType* = enum
- leNull = 0,
- leVar = 1,
- leNumLit = 2,
- leOp = 3,
- leAssign = 4,
- leLabel = 5,
- leGoto = 6,
- leIf = 7,
- leWhile = 8,
- leBreak = 9,
- leFuncCall = 10,
-
- LightExpr* = ref object
- case kind*: LightExprType
- of leVar:
- var_name*: LightVariable
- of leNumLit:
- value*: LightInt
- of leOp:
- left*: LightExpr
- right*: LightExpr
- operation*: LightOperation
- of leAssign:
- variable*: LightVariable
- expression*: LightExpr
- of leLabel, leGoto:
- label*: string
- of leIf, leWhile:
- condition*: LightExpr
- body*: seq[LightExpr]
- of leFuncCall:
- func_name*: string
- params*: seq[LightExpr]
- else:
- discard
-
-proc `$`*(exp: LightExpr): string =
- case exp.kind:
- of leVar: "Var[" & $exp.var_name & "]"
- of leNumLit: "Num[" & $exp.value & "]"
- of leOp: "Operation[" & $exp.operation & ", " & $exp.left & ", " & $exp.right & "]"
- of leAssign: "Assignment[" & $exp.variable & ", " & $exp.expression & "]"
- of leLabel: "Label[" & $exp.label & "]"
- of leGoto: "Goto[" & $exp.label & "]"
- of leIf: "If[" & $exp.condition & " -> " & $exp.body & "]"
- of leWhile: "While[" & $exp.condition & " -> " & $exp.body & "]"
- of leBreak: "Break"
- of leFuncCall: "FuncCall[" & exp.func_name & ", " & $exp.params & "]"
- else: ""
\ No newline at end of file
--- /dev/null
+import os
+import tables
+import ./types/types
+import ./types/ast
+import ./program
+import ../board/board
+import ../gfx/window
+
+type
+ LightWorker = ref object
+ var_1*, var_2*, var_3*, var_4*: LightInt
+ var_5*, var_6*, var_7*, var_8*: LightInt
+ pos_x*, pos_y*: LightInt
+
+ ExecFuncs = TableRef[string, proc(ec: ExecutionContext, args: openarray[LightInt]): LightInt]
+
+ ExecutionContext* = ref object
+ worker*: LightWorker
+ builtin_functions: ExecFuncs
+ defined_functions: TableRef[string, seq[LightExpr]]
+ running: bool
+
+proc MakeEmptyWorker(): LightWorker =
+ LightWorker()
+
+proc MakeExecutionContext*(funcs: ExecFuncs): ExecutionContext =
+ let worker = MakeEmptyWorker()
+ let defined_functions = newTable[string, seq[LightExpr]]()
+ ExecutionContext(
+ worker: worker,
+ builtin_functions: funcs,
+ defined_functions: defined_functions,
+ running: false
+ )
+
+proc ExecuteLines(ec: ExecutionContext, lines: seq[LightExpr]): LightInt
+
+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
+
+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
+
+ value
+
+proc EvalExpr(ec: ExecutionContext, exp: LightExpr): LightInt =
+ case exp.kind:
+ of leNull:
+ 0
+
+ of leVar:
+ GetVar(ec.worker, exp.var_name)
+
+ of leNumLit:
+ exp.value
+
+ of leOp:
+ let
+ left = EvalExpr(ec, exp.left)
+ right = EvalExpr(ec, exp.right)
+
+ case exp.operation:
+ of loAdd: left + right
+ of loSub: left - right
+ of loMul: left * right
+ of loDiv: left div right
+ of loMod: left mod right
+ of loGt:
+ if left > right: 1
+ else: 0
+ of loGte:
+ if left >= right: 1
+ else: 0
+ of loLt:
+ if left < right: 1
+ else: 0
+ of loLte:
+ if left <= right: 1
+ else: 0
+ of loEq:
+ if left == right: 1
+ else: 0
+ of loNeq:
+ if left != right: 1
+ else: 0
+
+ of leAssign:
+ let value = EvalExpr(ec, exp.expression)
+ SetVar(ec.worker, exp.variable, value)
+
+ of leIf:
+ let cond = EvalExpr(ec, exp.condition)
+ if cond != 0:
+ ExecuteLines(ec, exp.body)
+ else:
+ 0
+
+ of leWhile:
+ while ec.running:
+ let cond = EvalExpr(ec, exp.condition)
+ if cond == 0:
+ break
+
+ discard ExecuteLines(ec, exp.body)
+ 0
+
+ of leFuncCall:
+ if ec.builtin_functions.hasKey(exp.func_name):
+ var args = newSeq[LightInt]()
+ for param in exp.params:
+ args.add(EvalExpr(ec, param))
+ ec.builtin_functions[exp.func_name](ec, args)
+
+ elif ec.defined_functions.hasKey(exp.func_name):
+ ExecuteLines(ec, ec.defined_functions[exp.func_name])
+
+ else:
+ raise newException(ValueError, "Cannot call undefined function")
+
+ of leFuncDef:
+ if ec.defined_functions.hasKey(exp.def_func_name):
+ raise newException(ValueError, "Cannot redefine function")
+
+ else:
+ ec.defined_functions[exp.def_func_name] = exp.func_body
+ 1
+ else:
+ 0
+
+proc ExecuteLines(ec: ExecutionContext, lines: seq[LightExpr]): LightInt =
+ if not ec.running:
+ return 0
+
+ var last: LightInt
+ for line in lines:
+ last = EvalExpr(ec, line)
+ if not ec.running: break
+ last
+
+proc ExecuteProgram*(ec: ExecutionContext, prog: LightProgram): LightInt =
+ ec.running = true
+ ExecuteLines(ec, prog.code)
+
+proc StopExecution*(ec: ExecutionContext) =
+ ec.running = false
import parseutils
import sequtils
-import ./types
-import ./tokens
+import ./types/types
+import ./types/tokens
iterator Generate_tokens*(source: string): LightToken =
- for token, is_sep in strutils.tokenize(source, {' ', '\n', ';', '\t', '=', ',', '(', ')'}):
- if is_sep:
- if token.contains({'='}):
- yield LightToken(kind: ltEq)
- if token.contains({','}):
- yield LightToken(kind: ltParamDelim)
- if token.contains({'('}):
- yield LightToken(kind: ltParamStart)
- if token.contains({')'}):
- yield LightToken(kind: ltParamEnd)
- if token.contains({'\n', ';'}):
- yield LightToken(kind: ltExprDelim)
+ for line in strutils.split(source, "\n"):
+ if line.strip.startsWith("//"):
continue
- if token.startsWith('$'):
- let varString = token[1 .. ^1].toLowerAscii
- var varName: LightVariable
+ for token, is_sep in strutils.tokenize(line, {' ', ';', '\t', ',', '(', ')'}):
+ if is_sep:
+ if token.contains({','}):
+ yield LightToken(kind: ltParamDelim)
+ if token.contains({'('}):
+ yield LightToken(kind: ltParamStart)
+ if token.contains({')'}):
+ yield LightToken(kind: ltParamEnd)
+ if token.contains({';'}):
+ yield LightToken(kind: ltExprDelim)
+ continue
- if varString == "":
- raise newException(IOError, "Expected variable name")
- else:
- if varString == "mem_1": varName = var1
- elif varString == "mem_2": varName = var2
- elif varString == "mem_3": varName = var3
- elif varString == "mem_4": varName = var4
- elif varString == "mem_5": varName = var5
- elif varString == "mem_6": varName = var6
- elif varString == "mem_7": varName = var7
- elif varString == "mem_8": varName = var8
- elif varString == "pos_x": varName = var9
- elif varString == "pos_y": varName = var10
+ if token.startsWith('$'):
+ let varString = token[1 .. ^1].toLowerAscii
+ var varName: LightVariable
+
+ if varString == "":
+ raise newException(IOError, "Expected variable name")
else:
- raise newException(IOError, "Invalid variable name.")
+ if varString == "mem_1": varName = var1
+ elif varString == "mem_2": varName = var2
+ elif varString == "mem_3": varName = var3
+ elif varString == "mem_4": varName = var4
+ elif varString == "mem_5": varName = var5
+ elif varString == "mem_6": varName = var6
+ elif varString == "mem_7": varName = var7
+ elif varString == "mem_8": varName = var8
+ elif varString == "pos_x": varName = varX
+ elif varString == "pos_y": varName = varY
+ else:
+ raise newException(IOError, "Invalid variable name.")
- yield LightToken(kind: ltVar, var_name: varName)
+ yield LightToken(kind: ltVar, var_name: varName)
- elif token.startsWith('!'):
- let funcName = token[1..^1].toLowerAscii
- yield LightToken(kind: ltFunc, func_name: funcName)
+ elif token.startsWith('!'):
+ let funcName = token[1..^1].toLowerAscii
+ yield LightToken(kind: ltFunc, func_name: funcName)
- elif token == "=":
- yield LightToken(kind: ltEq)
+ elif token.startsWith('#'):
+ let funcName = token[1..^1].toLowerAscii
+ yield LightToken(kind: ltFuncDef, func_name: funcName)
- elif token.isDigit:
- var value: int
- discard parseutils.parseInt(token, value)
+ elif token == "=":
+ yield LightToken(kind: ltEq)
- yield LightToken(kind: ltNum, value: value.LightInt)
+ elif token.isDigit:
+ var value: int
+ discard parseutils.parseInt(token, value)
- elif token.toLowerAscii == "if":
- yield LightToken(kind: ltIf)
- elif token.toLowerAscii == "while":
- yield LightToken(kind: ltWhile)
- elif token.toLowerAscii == "break":
- yield LightToken(kind: ltBreak)
- elif token.toLowerAscii == "then" or token.toLowerAscii == "do" or token == "{":
- yield LightToken(kind: ltBlockStart)
- elif token.toLowerAscii == "end" or token == "}":
- yield LightToken(kind: ltBlockEnd)
+ yield LightToken(kind: ltNum, value: value.LightInt)
- elif token.toLowerAscii == "goto":
- yield LightToken(kind: ltGoto)
- elif token.startsWith(':'):
- let labelName = token[1 .. ^1]
- yield LightToken(kind: ltLabel, label_name: labelName)
+ elif token.toLowerAscii == "if":
+ yield LightToken(kind: ltIf)
+ elif token.toLowerAscii == "while":
+ yield LightToken(kind: ltWhile)
+ elif token.toLowerAscii == "break":
+ yield LightToken(kind: ltBreak)
+ elif token.toLowerAscii == "then" or token.toLowerAscii == "do" or token == "{":
+ yield LightToken(kind: ltBlockStart)
+ elif token.toLowerAscii == "end" or token == "}":
+ yield LightToken(kind: ltBlockEnd)
+
+ elif token.toLowerAscii == "goto":
+ yield LightToken(kind: ltGoto)
+ elif token.startsWith(':'):
+ let labelName = token[1 .. ^1]
+ yield LightToken(kind: ltLabel, label_name: labelName)
- else:
- case token:
- of "+":
- yield LightToken(kind: ltOp, operation: loAdd)
- of "-":
- yield LightToken(kind: ltOp, operation: loSub)
- of "*":
- yield LightToken(kind: ltOp, operation: loMul)
- of "/":
- yield LightToken(kind: ltOp, operation: loDiv)
- of "%":
- yield LightToken(kind: ltOp, operation: loMod)
- of "<":
- yield LightToken(kind: ltOp, operation: loLt)
- of "<=":
- yield LightToken(kind: ltOp, operation: loLte)
- of ">":
- yield LightToken(kind: ltOp, operation: loGt)
- of ">=":
- yield LightToken(kind: ltOp, operation: loGte)
- of "==":
- yield LightToken(kind: ltOp, operation: loEq)
- of "~=":
- yield LightToken(kind: ltOp, operation: loNeq)
else:
- raise newException(IOError, "Invalid token")
+ case token:
+ of "+":
+ yield LightToken(kind: ltOp, operation: loAdd)
+ of "-":
+ yield LightToken(kind: ltOp, operation: loSub)
+ of "*":
+ yield LightToken(kind: ltOp, operation: loMul)
+ of "/":
+ yield LightToken(kind: ltOp, operation: loDiv)
+ of "%":
+ yield LightToken(kind: ltOp, operation: loMod)
+ of "<":
+ yield LightToken(kind: ltOp, operation: loLt)
+ of "<=":
+ yield LightToken(kind: ltOp, operation: loLte)
+ of ">":
+ yield LightToken(kind: ltOp, operation: loGt)
+ of ">=":
+ yield LightToken(kind: ltOp, operation: loGte)
+ of "==":
+ yield LightToken(kind: ltOp, operation: loEq)
+ of "~=":
+ yield LightToken(kind: ltOp, operation: loNeq)
+ else:
+ raise newException(IOError, "Invalid token")
+
+ yield LightToken(kind: ltExprDelim)
-import ./types
-import ./tokens
-import ./ast
+import ./types/types
+import ./types/tokens
+import ./types/ast
import ../utils/iter
params: params
)
+ elif curr.kind == ltFuncDef:
+ if parser.tokens.Current.kind != ltBlockStart:
+ raise newException(ValueError, "Expected block start after function definition")
+
+ parser.tokens.Step()
+ let body = Parse_block(parser.tokens, ltExprDelim, ltBlockEnd)
+
+ return LightExpr(
+ kind: leFuncDef,
+ def_func_name: curr.func_name,
+ func_body: body
+ )
+
+ else:
+ return LightExpr(
+ kind: leNull
+ )
+
iterator Parse_tokens*(tokens: seq[LightToken]): LightExpr =
var parser = CreateParser(tokens)
while not parser.tokens.ReachedEnd:
--- /dev/null
+import sequtils
+import tables
+import ./types/ast
+import ./lexer
+import ./parser
+
+type
+ LightProgram* = ref object
+ code*: seq[LightExpr]
+
+proc LoadProgram*(file_name: string): LightProgram =
+ let source_code = readFile(file_name)
+ let tokens = toSeq(lexer.GenerateTokens(source_code))
+ let code = toSeq(parser.ParseTokens(tokens))
+
+ LightProgram(code: code)
+++ /dev/null
-import ./types
-
-type
- LightTokenType* = enum
- ltNull,
- ltVar, ltNum,
- ltExprDelim,
- ltLabel, ltGoto,
- ltIf, ltWhile,
- ltBlockStart, ltBlockEnd,
- ltBreak,
- ltFunc,
- ltParamStart, ltParamEnd,
- ltParamDelim,
- ltOp, ltEq
-
- LightToken* = ref object
- case kind*: LightTokenType
- of ltVar:
- var_name*: LightVariable
- of ltNum:
- value*: LightInt
- of ltLabel:
- label_name*: string
- of ltFunc:
- func_name*: string
- of ltOp:
- operation*: LightOperation
- 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 var9: "POS_X"
- of var10: "POS_Y"
-
-proc `$`*(token: LightToken): string =
- return
- case token.kind:
- of ltNull: "NullToken"
- of ltVar: "VarToken[" & $token.var_name & "]"
- of ltEq: "EqualsToken"
- of ltNum: "NumberToken[" & $token.value & "]"
- of ltExprDelim: "ExprDelimToken"
- of ltLabel: "LabelToken[" & token.label_name & "]"
- of ltGoto: "GotoToken"
- of ltIf: "IfToken"
- of ltWhile: "WhileToken"
- of ltBreak: "BreakToken"
- of ltBlockStart: "BlockStartToken"
- of ltBlockEnd: "BlockEndToken"
- of ltFunc: "FunctionToken[" & token.func_name & "]"
- of ltParamStart: "ParamStartToken"
- of ltParamEnd: "ParamEndToken"
- of ltParamDelim: "ParamDelimToken"
- of ltOp: "OpeartionToken[" & $token.operation & "]"
- else: "UndefinedToken"
\ No newline at end of file
+++ /dev/null
-type
- LightVariable* = enum
- var1 = 0, var2 = 1, var3 = 2, var4 = 3,
- var5 = 4, var6 = 5, var7 = 6, var8 = 7,
- var9 = 8, var10 = 9
-
- LightOperation* = enum
- loAdd, loSub, loMul, loDiv, loMod,
- loGt, loGte, loLt, loLte, loEq, loNeq
-
- LightInt* = int32
--- /dev/null
+import ./types
+import ./tokens
+
+type
+ LightExprType* = enum
+ leNull = 0,
+ leVar = 1,
+ leNumLit = 2,
+ leOp = 3,
+ leAssign = 4,
+ leLabel = 5,
+ leGoto = 6,
+ leIf = 7,
+ leWhile = 8,
+ leBreak = 9,
+ leFuncCall = 10,
+ leFuncDef = 11,
+
+ LightExpr* = ref object
+ case kind*: LightExprType
+ of leVar:
+ var_name*: LightVariable
+ of leNumLit:
+ value*: LightInt
+ of leOp:
+ left*: LightExpr
+ right*: LightExpr
+ operation*: LightOperation
+ of leAssign:
+ variable*: LightVariable
+ expression*: LightExpr
+ of leLabel, leGoto:
+ label*: string
+ of leIf, leWhile:
+ condition*: LightExpr
+ body*: seq[LightExpr]
+ of leFuncCall:
+ func_name*: string
+ params*: seq[LightExpr]
+ of leFuncDef:
+ def_func_name*: string
+ func_body*: seq[LightExpr]
+ else:
+ discard
+
+proc `$`*(exp: LightExpr): string =
+ case exp.kind:
+ of leVar: "Var[" & $exp.var_name & "]"
+ of leNumLit: "Num[" & $exp.value & "]"
+ of leOp: "Operation[" & $exp.operation & ", " & $exp.left & ", " & $exp.right & "]"
+ of leAssign: "Assignment[" & $exp.variable & ", " & $exp.expression & "]"
+ of leLabel: "Label[" & $exp.label & "]"
+ of leGoto: "Goto[" & $exp.label & "]"
+ of leIf: "If[" & $exp.condition & " -> " & $exp.body & "]"
+ of leWhile: "While[" & $exp.condition & " -> " & $exp.body & "]"
+ of leBreak: "Break"
+ of leFuncCall: "FuncCall[" & exp.func_name & ", " & $exp.params & "]"
+ of leFuncDef: "FuncDef[" & exp.def_func_name & ", " & $exp.func_body & "]"
+ else: ""
\ No newline at end of file
--- /dev/null
+import ./types
+
+type
+ LightTokenType* = enum
+ ltNull,
+ ltVar, ltNum,
+ ltExprDelim,
+ ltLabel, ltGoto,
+ ltIf, ltWhile,
+ ltBlockStart, ltBlockEnd,
+ ltBreak,
+ ltFunc,
+ ltParamStart, ltParamEnd,
+ ltParamDelim,
+ ltFuncDef,
+ ltOp, ltEq
+
+ LightToken* = ref object
+ case kind*: LightTokenType
+ of ltVar:
+ var_name*: LightVariable
+ of ltNum:
+ value*: LightInt
+ of ltLabel:
+ label_name*: string
+ of ltFunc, ltFuncDef:
+ func_name*: string
+ of ltOp:
+ operation*: LightOperation
+ 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:
+ of ltNull: "NullToken"
+ of ltVar: "VarToken[" & $token.var_name & "]"
+ of ltEq: "EqualsToken"
+ of ltNum: "NumberToken[" & $token.value & "]"
+ of ltExprDelim: "ExprDelimToken"
+ of ltLabel: "LabelToken[" & token.label_name & "]"
+ of ltGoto: "GotoToken"
+ of ltIf: "IfToken"
+ of ltWhile: "WhileToken"
+ of ltBreak: "BreakToken"
+ of ltBlockStart: "BlockStartToken"
+ of ltBlockEnd: "BlockEndToken"
+ of ltFunc: "FunctionToken[" & token.func_name & "]"
+ of ltParamStart: "ParamStartToken"
+ of ltParamEnd: "ParamEndToken"
+ of ltParamDelim: "ParamDelimToken"
+ of ltFuncDef: "FuncDefToken[" & token.func_name & "]"
+ of ltOp: "OpeartionToken[" & $token.operation & "]"
+ else: "UndefinedToken"
\ No newline at end of file
--- /dev/null
+type
+ LightVariable* = enum
+ var1 = 0, var2 = 1, var3 = 2, var4 = 3,
+ var5 = 4, var6 = 5, var7 = 6, var8 = 7,
+ varX = 8, varY = 9
+
+ LightOperation* = enum
+ loAdd, loSub, loMul, loDiv, loMod,
+ loGt, loGte, loLt, loLte, loEq, loNeq
+
+ LightInt* = int32