From: Brendan Hansen Date: Sat, 15 Dec 2018 21:39:20 +0000 (-0600) Subject: WORKING VERSION X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=af20e156972bd671c3fc70284131d457328185d9;p=light.git WORKING VERSION --- diff --git a/christmas_proj b/christmas_proj index 8bf1cf3..9482429 100755 Binary files a/christmas_proj and b/christmas_proj differ diff --git a/christmas_proj.nimble b/christmas_proj.nimble index 88bb56a..182ef92 100644 --- a/christmas_proj.nimble +++ b/christmas_proj.nimble @@ -15,5 +15,5 @@ requires "opengl >= 1.2.0" requires "glfw" task run, "Run project": - exec("nimble build") + exec("nimble build -d:release") exec("./christmas_proj") \ No newline at end of file diff --git a/data/progs/fibcol.lgt b/data/progs/fibcol.lgt new file mode 100644 index 0000000..11e416d --- /dev/null +++ b/data/progs/fibcol.lgt @@ -0,0 +1,21 @@ +$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() + } +} + diff --git a/data/progs/first.lgt b/data/progs/first.lgt new file mode 100644 index 0000000..61b8e9e --- /dev/null +++ b/data/progs/first.lgt @@ -0,0 +1,43 @@ +$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) diff --git a/data/progs/test.lgt b/data/progs/test.lgt index 93a5427..a719715 100644 --- a/data/progs/test.lgt +++ b/data/progs/test.lgt @@ -1,15 +1,20 @@ -$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 diff --git a/src/board/board.nim b/src/board/board.nim index 35101fd..aecfcdf 100644 --- a/src/board/board.nim +++ b/src/board/board.nim @@ -2,7 +2,7 @@ import opengl import ../gfx/glutils type - LightBoard = ref object + LightBoard* = ref object width: int height: int data: ref array[1024 * 1024, GLuint] diff --git a/src/christmas_proj.nim b/src/christmas_proj.nim index 49b211e..229b07b 100644 --- a/src/christmas_proj.nim +++ b/src/christmas_proj.nim @@ -1,15 +1,13 @@ 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 @@ -17,75 +15,56 @@ proc key_down(window: glfw.Window, key, scancode, action, modifier: cint) {.cdec 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() diff --git a/src/gfx/window.nim b/src/gfx/window.nim index 6a80640..1b7cefa 100644 --- a/src/gfx/window.nim +++ b/src/gfx/window.nim @@ -2,7 +2,7 @@ import glfw3 as glfw import opengl type - Window* = object + Window* = ref object window: glfw.Window width, height: cint title: cstring diff --git a/src/lang/ast.nim b/src/lang/ast.nim deleted file mode 100644 index e0fee97..0000000 --- a/src/lang/ast.nim +++ /dev/null @@ -1,54 +0,0 @@ -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 diff --git a/src/lang/executer.nim b/src/lang/executer.nim new file mode 100644 index 0000000..4988ee2 --- /dev/null +++ b/src/lang/executer.nim @@ -0,0 +1,165 @@ +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 diff --git a/src/lang/lexer.nim b/src/lang/lexer.nim index a5acc32..6e754c8 100644 --- a/src/lang/lexer.nim +++ b/src/lang/lexer.nim @@ -2,99 +2,107 @@ import strutils 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) diff --git a/src/lang/parser.nim b/src/lang/parser.nim index b040077..1019884 100644 --- a/src/lang/parser.nim +++ b/src/lang/parser.nim @@ -1,7 +1,7 @@ -import ./types -import ./tokens -import ./ast +import ./types/types +import ./types/tokens +import ./types/ast import ../utils/iter @@ -128,6 +128,24 @@ func NextExpr(parser: LightParser, prev: LightExpr, stop_at: set[LightTokenType] 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: diff --git a/src/lang/program.nim b/src/lang/program.nim new file mode 100644 index 0000000..1dbfce0 --- /dev/null +++ b/src/lang/program.nim @@ -0,0 +1,16 @@ +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) diff --git a/src/lang/tokens.nim b/src/lang/tokens.nim deleted file mode 100644 index 9a9cdcb..0000000 --- a/src/lang/tokens.nim +++ /dev/null @@ -1,65 +0,0 @@ -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 diff --git a/src/lang/types.nim b/src/lang/types.nim deleted file mode 100644 index 847ff5d..0000000 --- a/src/lang/types.nim +++ /dev/null @@ -1,11 +0,0 @@ -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 diff --git a/src/lang/types/ast.nim b/src/lang/types/ast.nim new file mode 100644 index 0000000..1cd98b6 --- /dev/null +++ b/src/lang/types/ast.nim @@ -0,0 +1,59 @@ +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 diff --git a/src/lang/types/tokens.nim b/src/lang/types/tokens.nim new file mode 100644 index 0000000..b9ceaec --- /dev/null +++ b/src/lang/types/tokens.nim @@ -0,0 +1,67 @@ +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 diff --git a/src/lang/types/types.nim b/src/lang/types/types.nim new file mode 100644 index 0000000..d17d6d8 --- /dev/null +++ b/src/lang/types/types.nim @@ -0,0 +1,11 @@ +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