From: Brendan Hansen Date: Tue, 18 Dec 2018 06:57:33 +0000 (-0600) Subject: arbitrary variable names; variable scopes; bug fixes X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=99a1222f0a19d38192a5b15e2a49eb2593e2b7fa;p=light.git arbitrary variable names; variable scopes; bug fixes --- diff --git a/christmas_proj b/christmas_proj index b4796ba..1c1efbc 100755 Binary files a/christmas_proj and b/christmas_proj differ diff --git a/christmas_proj.nimble b/christmas_proj.nimble index c147fcd..c935d1f 100644 --- a/christmas_proj.nimble +++ b/christmas_proj.nimble @@ -13,8 +13,8 @@ bin = @["christmas_proj"] requires "nim >= 0.19.0" requires "docopt >= 0.6.8" requires "opengl >= 1.2.0" -requires "glfw" +requires "nimrod-glfw" task run, "Run project": exec("nimble build -d:release") - exec("./christmas_proj") \ No newline at end of file + exec("./christmas_proj") diff --git a/data/progs/avg.lgt b/data/progs/avg.lgt deleted file mode 100644 index 3128585..0000000 --- a/data/progs/avg.lgt +++ /dev/null @@ -1,81 +0,0 @@ - -@FLOOD_WITH_RANDOM() { - $m6 = (256 * 256 * 256) - 1 - $m7 = !GET_WIDTH() - $m8 = !GET_HEIGHT() - - $y = 0 - while $y < $m8 { - $x = 0 - while $x < $m7 { - !SET_COL(!RANDOM($m6)) - $x = $x + 1 - } - $y = $y + 1 - } -} - -//change 1, 2, 3 4, 7, 8 -@TAKE_AVERAGE() { - //Red, Green and Blue Sum - $m1 = 0 - $m2 = 0 - $m3 = 0 - //Count - $m4 = 0 - - $m7 = $x + 1 - $m8 = $y + 1 - - $y = $y - 1 - while $y <= $m8 { - $x = $m7 - 2 - while $x <= $m7 { - if !IN_BOUNDS($x, $y) { - $m1 = $m1 + !GET_R() - $m2 = $m2 + !GET_G() - $m3 = $m3 + !GET_B() - - $m4 = $m4 + 1 - } - - $x = $x + 1 - } - $y = $y + 1 - } - $x = $x - 2 - $y = $y - 2 - - if $m4 > 0 { - $m1 = $m1 / $m4 - $m2 = $m2 / $m4 - $m3 = $m3 / $m4 - $m1 = $m1 * 256 * 256 - $m2 = $m2 * 256 - !SET_COL($m1 + $m2 + $m3) - } -} - -!FLOOD_WITH_RANDOM() - -!SAY(!GET_WIDTH()) -!SAY(!GET_HEIGHT()) - -$m5 = 30 -while 1 { - !RENDER() - $m5 = $m5 - 1 - if $m5 <= 0 { - $m5 = 30 - - $y = 0 - while $y < !GET_HEIGHT() { - $x = 0 - while $x < !GET_WIDTH() { - !TAKE_AVERAGE() - $x = $x + 1 - } - $y = $y + 1 - } - } -} diff --git a/data/progs/first.lgt b/data/progs/first.lgt deleted file mode 100644 index 748ee79..0000000 --- a/data/progs/first.lgt +++ /dev/null @@ -1,43 +0,0 @@ -$x = 0 -$y = 10 -$m8 = 1 - -#move_diag { - $x = $x + $m8 - $y = $y + $m8 -} - -#swap_xy { - $m1 = $x - $x = $y - $y = $m1 -} - -$m3 = 100 -while $x <= !GET_WIDTH() { - $m3 = $m3 + 4 - if $m3 >= 256 { - $m3 = $m3 - 156 - } - - !set_col($m3) - !move_diag() - !swap_xy() - !render() -} - -$x = !GET_WIDTH() - 15 -$y = !GET_HEIGHT() - 1 -$m8 = 0 - 1 - -while $x >= 0 { - !set_col(255) - !move_diag() - !render() -} - -!say($x) -$m2 = if $x < 0 { - 1000 -} -!say($m2) diff --git a/data/progs/gol.lgt b/data/progs/gol.lgt deleted file mode 100644 index 40c1fbf..0000000 --- a/data/progs/gol.lgt +++ /dev/null @@ -1,99 +0,0 @@ -//Assumes 128 by 128 board -@BOARD_WIDTH() { !GET_WIDTH() } -@BOARD_HEIGHT() { !GET_HEIGHT() } - -@CELL_ALIVE() { 255 } -@CELL_DEAD() { 0 } - -// Set up initial board -$y = 0 -while $y < !BOARD_HEIGHT() { - $x = 0 - while $x < !BOARD_WIDTH() { - if !random(100) >= 50 { - !set_r(!CELL_ALIVE()) - } else { - !set_r(!CELL_DEAD()) - } - $x = $x + 1 - } - $y = $y + 1 -} - -@UPDATE_CURRENT() { - //Neighbor count - $m1 = 0 - - $x = $x - 1 - $y = $y - 1 - - $m1 = $m1 + !get_a() == !CELL_ALIVE() - $x = $x + 1 - $m1 = $m1 + !get_a() == !CELL_ALIVE() - $x = $x + 1 - $m1 = $m1 + !get_a() == !CELL_ALIVE() - $x = $x - 2 - $y = $y + 1 - $m1 = $m1 + !get_a() == !CELL_ALIVE() - $x = $x + 2 - $m1 = $m1 + !get_a() == !CELL_ALIVE() - $x = $x - 2 - $y = $y + 1 - $m1 = $m1 + !get_a() == !CELL_ALIVE() - $x = $x + 1 - $m1 = $m1 + !get_a() == !CELL_ALIVE() - $x = $x + 1 - $m1 = $m1 + !get_a() == !CELL_ALIVE() - - $x = $x - 1 - $y = $y - 1 - - if !get_a() == !CELL_ALIVE() { - if ($m1 < 2) | ($m1 > 3) { - !set_r(!CELL_DEAD()) - } - } else { - if $m1 == 3 { - !set_r(!CELL_ALIVE()) - } - } -} - -@COPY_BOARD() { - $y = 0 - while $y < !BOARD_HEIGHT() { - $x = 0 - while $x < !BOARD_WIDTH() { - !set_a(!get_r()) - - $x = $x + 1 - } - $y = $y + 1 - } -} - -//Big render / update loop -$m7 = 30 -while 1 { - //Draw the board - !render() - - $m7 = $m7 - 1 - if $m7 <= 0 { - $m7 = 1 - - !COPY_BOARD() - - $y = 0 - while $y < !BOARD_HEIGHT() { - $x = 0 - while $x < !BOARD_WIDTH() { - !UPDATE_CURRENT() - $x = $x + 1 - } - $y = $y + 1 - } - } -} - -(5 > 4) & (7 > 10) \ No newline at end of file diff --git a/data/progs/gol.light b/data/progs/gol.light new file mode 100644 index 0000000..4c1ddec --- /dev/null +++ b/data/progs/gol.light @@ -0,0 +1,94 @@ +//Assumes 128 by 128 board +var $board_width = !get_width() +var $board_height = !get_height() + +var $cell_alive = 255 +var $cell_dead = 0 + +@create_board() { + var $x + var $y + + // Set up initial board + $y = 0 + while $y < $board_height { + $x = 0 + while $x < $board_width { + if !random(100) >= 50 { + !set_r($x, $y, $cell_alive) + } else { + !set_r($x, $y, $cell_dead) + } + $x = $x + 1 + } + $y = $y + 1 + } +} + +@update_cell($x, $y) { + var $neighbors = 0 + var $x_off + var $y_off + + $y_off = -1 + while $y_off <= 1 { + $x_off = -1 + while $x_off <= 1 { + if ($y_off ~= 0) | ($x_off ~= 0) { + if !get_a($x_off + $x, $y_off + $y) == $cell_alive { + $neighbors = $neighbors + 1 + } + } + $x_off = $x_off + 1 + } + $y_off = $y_off + 1 + } + + if !get_a($x, $y) == $cell_alive { + if ($neighbors < 2) | ($neighbors > 3) { + !set_r($x, $y, $cell_dead) + } + } else { + if $neighbors == 3 { + !set_r($x, $y, $cell_alive) + } + } +} + +@copy_board() { + var $x + var $y + + $y = 0 + while $y < $board_height { + $x = 0 + while $x < $board_width { + !set_a($x, $y, !get_r($x, $y)) + + $x = $x + 1 + } + $y = $y + 1 + } +} + +!create_board() + +//Big render / update loop +var $x +var $y +while 1 { + //Draw the board + !render() + + !copy_board() + + $y = 0 + while $y < $board_height { + $x = 0 + while $x < $board_width { + !update_cell($x, $y) + $x = $x + 1 + } + $y = $y + 1 + } +} diff --git a/data/progs/maze.lgt b/data/progs/maze.lgt deleted file mode 100644 index f450a50..0000000 --- a/data/progs/maze.lgt +++ /dev/null @@ -1,108 +0,0 @@ -@push_pos() { - $m1 = ($y * 256 * 256) + $x - - !step_to_linear(0) - !step_to_linear(!get_col() + 1) - - !set_col($m1) - - !step_to_linear(0) - !set_col(!get_col() + 1) - - $x = $m1 % (256 * 256) - $y = $m1 / (256 * 256) -} - -@pop_pos() { - !step_to_linear(0) - !step_to_linear(!get_col()) - $m1 = !get_col() - //!set_col(16777215) - - !step_to_linear(0) - !set_col(!get_col() - 1) - $x = $m1 % (256 * 256) - $y = $m1 / (256 * 256) -} - -@get_stack_height() { - !push_pos() - !step_to_linear(0) - $m2 = !get_col() - 1 - !pop_pos() - $m2 -} - -//Fills memory with defaults -$y = 20 -while $y < !get_height() { - $x = 0 - while $x < !get_width() { - !set_col(255) - $x = $x + 1 - } - $y = $y + 1 -} - - -$x = 1 -$y = 21 -!push_pos() -!set_col(50) -while !get_stack_height() > 0 { - !pop_pos() - !push_pos() - - $m1 = 0 - $y = $y - 2 - $m1 = $m1 + if !get_col() == 255 { 1 } else { 0 } - $y = $y + 2 - $x = $x - 2 - $m1 = $m1 + if !get_col() == 255 { 1 } else { 0 } - $x = $x + 4 - $m1 = $m1 + if !get_col() == 255 { 1 } else { 0 } - $x = $x - 2 - $y = $y + 2 - $m1 = $m1 + if !get_col() == 255 { 1 } else { 0 } - $y = $y - 2 - - if $m1 { - while 1 { - //Random direction - $m7 = !random(4) - - // 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 !in_bounds($x + $m5, $y + $m6) { - !push_pos() - !push_pos() - $x = $x + $m5 - $y = $y + $m6 - if !get_col() == 255 { - !set_col(50) - !pop_pos() - $x = $x + $m5 / 2 - $y = $y + $m6 / 2 - !set_col(50) - !pop_pos() - $x = $x + $m5 - $y = $y + $m6 - !push_pos() - break - } else { - !pop_pos() - !pop_pos() - } - } - } - } else { - !pop_pos() - } - !render() -} diff --git a/data/progs/maze.light b/data/progs/maze.light new file mode 100644 index 0000000..40858b7 --- /dev/null +++ b/data/progs/maze.light @@ -0,0 +1,100 @@ +@get_linear($pos) { + !get_col($pos % !get_width(), $pos / !get_width()) +} + +@set_linear($pos, $val) { + !set_col($pos % !get_width(), $pos / !get_width(), $val) +} + +@push_pos($x, $y) { + var $color_enc = ($y * 256 * 256) + $x + + var $off = !get_col(0, 0) + 1 + !set_linear($off, $color_enc) + + !set_col(0, 0, $off) +} + +@top_pos() { + var $off = !get_col(0, 0) + !get_linear($off) +} + +@pop_pos() { + var $off = !get_col(0, 0) + !set_linear($off, 0) + !set_col(0, 0, $off - 1) + 0 +} + +@get_stack_height() { + !get_col(0, 0) +} + +//Fills memory with defaults +@clear_board() { + var $x + var $y = 20 + while $y < !get_height() { + $x = 0 + while $x < !get_width() { + !set_col($x, $y, 255) + $x = $x + 1 + } + $y = $y + 1 + } +} + +@generate_maze() { + var $x = 1 + var $y = 21 + var $loc + var $available_count + var $dir + var $dx + var $dy + + !push_pos($x, $y) + !set_col($x, $y, 50) + while !get_stack_height() > 0 { + $loc = !top_pos() + $x = $loc % (256 * 256) + $y = $loc / (256 * 256) + + $available_count = 0 + $available_count = $available_count + !get_col($x, $y - 2) == 255 + $available_count = $available_count + !get_col($x - 2, $y) == 255 + $available_count = $available_count + !get_col($x + 2, $y) == 255 + $available_count = $available_count + !get_col($x, $y + 2) == 255 + + if $available_count { + while 1 { + //Random direction + $dir = !random(4) + + // dx and dy + $dx = $dy = 0 + + if $dir == 0 { $dx = -2 } + if $dir == 1 { $dx = 2 } + if $dir == 2 { $dy = 2 } + if $dir == 3 { $dy = -2 } + + if !in_bounds($x + $dx, $y + $dy) { + if !get_col($x + $dx, $y + $dy) == 255 { + !set_col($x + $dx, $y + $dy, 50) + !set_col($x + $dx / 2, $y + $dy / 2, 50) + !push_pos($x + $dx, $y + $dy) + break + } + } + } + } else { + !pop_pos() + } + !render() + } +} + +!clear_board() +!generate_maze() diff --git a/data/progs/new_syntax.light b/data/progs/new_syntax.light index 48ff7a1..101ad5a 100644 --- a/data/progs/new_syntax.light +++ b/data/progs/new_syntax.light @@ -1,23 +1,18 @@ -@test_func($p1, $p2) { - $p1 + $p2 -} -@move_to($p1, $p2) { - $x = $p1 - $y = $p2 -} +var $param = 1000 -$p1 = 100 -$m1 = 0 -@rec($p1) { - $m1 = $m1 + 1 - if $p1 <= 1 { - 1 - } else { - !test_func($p1, !rec($p1 - 1)) - } +var $asdf = 10 +@test_func($param) { + !say($asdf) + var $asdf = 1234 + !say($asdf) + !say($param + $test) + !set_col($param, $param + $test, ($param * $test) + 200) } -!say(!rec($p1), $m1) -!say($p1) +var $test = 4 + +!test_func($asdf) +!say($param) +!render() \ No newline at end of file diff --git a/data/progs/sorts.light b/data/progs/sorts.light new file mode 100644 index 0000000..0725b02 --- /dev/null +++ b/data/progs/sorts.light @@ -0,0 +1,177 @@ +var $width = !get_width() +var $height = !get_height() + +//Util functions +@get_linear($pos) { + !get_col($pos % $width, $pos / $width) +} + +@set_linear($pos, $val) { + !set_col($pos % $width, $pos / $width, $val) +} + +@swap_linear($p1, $p2) { + var $tmp = !get_col($p1 % $width, $p1 / $width) + !set_col($p1 % $width, $p1 / $width, !get_col($p2 % $width, $p2 / $width)) + !set_col($p2 % $width, $p2 / $width, $tmp) +} + +@fill_with_random() { + var $x = 0 + var $y = 0 + var $rgb + + $y = 0 + while $y < !get_height() { + $x = 0 + while $x < !get_width() { + $rgb = !random(2) + + !set_r($x, $y, if $rgb == 0 { !random(255) }) + !set_g($x, $y, if $rgb == 1 { !random(255) }) + !set_b($x, $y, if $rgb == 2 { !random(255) }) + $x = $x + 1 + } + $y = $y + 1 + } +} + +//Sorting functions + +@selection_sort($start, $end) { + var $tmp + var $small_val + var $small_ind + var $j + var $i = $start + while $i < $end { + $small_val = !get_linear($i) + $small_ind = $i + $j = $i + 1 + while $j < $end { + if !get_linear($j) < $small_val { + $small_val = !get_linear($j) + $small_ind = $j + } + + $j = $j + 1 + } + + !swap_linear($i, $small_ind) + !render() + $i = $i + 1 + } +} + +@bubble_sort($start, $end) { + var $i + var $j + var $tmp + + $i = 0 + while $i < ($end - 1) { + $j = 0 + while $j < ($end - ($i + 1)) { + if !get_linear($j) > !get_linear($j + 1) { + !swap_linear($j, $j + 1) + } + + $j = $j + 1 + } + !render() + $i = $i + 1 + } +} + +@insertion_sort($start, $end) { + var $tmp + var $j = 0 + var $i = $start + 1 + while $i < $end { + $j = $i + while !get_linear($j) < !get_linear($j - 1) { + !swap_linear($j, $j - 1) + $j = $j - 1 + } + + $i = $i + 1 + !render() + } +} + +@shell_sort($start, $end) { + var $k + var $i + var $n + + $k = $end / 2 + while $k > 0 { + $i = $k + while $i < $end { + $n = $i - $k + while $n >= 0 { + if !get_linear($n + $k) >= !get_linear($n) { + break + } else { + !swap_linear($n, $n + $k) + } + + $n = $n - $k + } + + //Used to make it look cool + if ($i % 4) == 0 { !render() } + $i = $i + 1 + } + $k = $k / 2 + } +} + +@quick_partition($low, $high) { + var $pivot = !get_linear($high) + var $i = $low + var $j = $low + while $j < $high { + if !get_linear($j) <= $pivot { + !swap_linear($i, $j) + $i = $i + 1 + } + + $j = $j + 1 + } + + !swap_linear($i, $high) + $i +} + +@quick_sort($low, $high) { + if $low < $high { + var $pi = !quick_partition($low, $high) + + !quick_sort($low, $pi - 1) + !render() + !quick_sort($pi + 1, $high) + !render() + } +} + + +!fill_with_random() +!render() +!bubble_sort(0, !get_width() * !get_height()) + +!fill_with_random() +!render() +!selection_sort(0, !get_width() * !get_height()) + +!fill_with_random() +!render() +!insertion_sort(0, !get_width() * !get_height()) + +!fill_with_random() +!render() +!shell_sort(0, !get_width() * !get_height()) + +!fill_with_random() +!render() +!quick_sort(0, (!get_width() * !get_height()) - 1) diff --git a/src/board/board.nim b/src/board/board.nim index 3f48144..0f0617c 100644 --- a/src/board/board.nim +++ b/src/board/board.nim @@ -125,7 +125,7 @@ proc InitRendering*(board: LightBoard) = glGenBuffers(1, board.colorBufferObject.addr) glBindBuffer(GL_ARRAY_BUFFER, board.colorBufferObject) - glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 4 * board.width * board.height, board.colors.addr, GL_DYNAMIC_DRAW) + glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 4 * board.width * board.height, board.colors[].addr, GL_DYNAMIC_DRAW) glEnableVertexAttribArray(1) glVertexAttribDivisor(1, 1) glVertexAttribPointer(1, 4, cGL_FLOAT, GL_FALSE, 16.GLsizei, nil) diff --git a/src/christmas_proj.nim b/src/christmas_proj.nim index da14717..2217b11 100644 --- a/src/christmas_proj.nim +++ b/src/christmas_proj.nim @@ -43,64 +43,49 @@ proc CreateFuncs(window: gfx_window.Window, board: LightBoard): ExecFuncs = ), "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) + board.SetCol(args[0].int, args[1].int, args[2].GLuint) ), "set_a": (proc(ec: ExecutionContext, args: openarray[int32]): int32 {.closure.} = - board.SetA(ec.worker.pos_x.int, ec.worker.pos_y.int, args[0].GLuint) + board.SetA(args[0].int, args[1].int, args[2].GLuint) ), "set_r": (proc(ec: ExecutionContext, args: openarray[int32]): int32 {.closure.} = - board.SetR(ec.worker.pos_x.int, ec.worker.pos_y.int, args[0].GLuint) + board.SetR(args[0].int, args[1].int, args[2].GLuint) ), "set_g": (proc(ec: ExecutionContext, args: openarray[int32]): int32 {.closure.} = - board.SetG(ec.worker.pos_x.int, ec.worker.pos_y.int, args[0].GLuint) + board.SetG(args[0].int, args[1].int, args[2].GLuint) ), "set_b": (proc(ec: ExecutionContext, args: openarray[int32]): int32 {.closure.} = - board.SetB(ec.worker.pos_x.int, ec.worker.pos_y.int, args[0].GLuint) + board.SetB(args[0].int, args[1].int, args[2].GLuint) ), "get_col": (proc(ec: ExecutionContext, args: openarray[int32]): int32 {.closure.} = - board.GetCol(ec.worker.pos_x.int, ec.worker.pos_y.int).int32 + board.GetCol(args[0].int, args[1].int).int32 ), "get_a": (proc(ec: ExecutionContext, args: openarray[int32]): int32 {.closure.} = - board.GetA(ec.worker.pos_x.int, ec.worker.pos_y.int).int32 + board.GetA(args[0].int, args[1].int).int32 ), "get_r": (proc(ec: ExecutionContext, args: openarray[int32]): int32 {.closure.} = - board.GetR(ec.worker.pos_x.int, ec.worker.pos_y.int).int32 + board.GetR(args[0].int, args[1].int).int32 ), "get_g": (proc(ec: ExecutionContext, args: openarray[int32]): int32 {.closure.} = - board.GetG(ec.worker.pos_x.int, ec.worker.pos_y.int).int32 + board.GetG(args[0].int, args[1].int).int32 ), "get_b": (proc(ec: ExecutionContext, args: openarray[int32]): int32 {.closure.} = - board.GetB(ec.worker.pos_x.int, ec.worker.pos_y.int).int32 + board.GetB(args[0].int, args[1].int).int32 ), "random": (proc(ec: ExecutionContext, args: openarray[int32]): int32 {.closure.} = random.rand(args[0].int).int32 ), - "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 - ), - - "step_to_linear": (proc(ec: ExecutionContext, args: openarray[int32]): int32 {.closure.} = - ec.worker.pos_x = args[0] mod (board.width.int32) - ec.worker.pos_y = args[0] div (board.width.int32) - ), - "halt": (proc(ec: ExecutionContext, args: openarray[int32]): int32 {.closure.} = ec.StopExecution() ), diff --git a/src/lang/executer.nim b/src/lang/executer.nim index cb76310..50061fc 100644 --- a/src/lang/executer.nim +++ b/src/lang/executer.nim @@ -10,18 +10,9 @@ 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 - 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 + Environment* = ref object + values: TableRef[LightVariable, LightInt] + parent: Environment ExecFuncs* = TableRef[string, proc(ec: ExecutionContext, args: openarray[LightInt]): LightInt] @@ -30,36 +21,24 @@ type body: seq[LightExpr] ExecutionContext* = ref object - worker*: LightWorker + vars: Environment builtin_functions: ExecFuncs 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 = - let worker = LightWorker() - let param_ctx = new(array[MAX_STACK_HEIGHT, PContext]) - worker.param_stack = PStack( - stack: param_ctx, - size: 1 +proc MakeEnvironment*(parent: Environment): Environment = + let values = newTable[LightVariable, LightInt]() + Environment( + values: values, + parent: parent ) - worker proc MakeExecutionContext*(funcs: ExecFuncs): ExecutionContext = - let worker = MakeEmptyWorker() + let env = MakeEnvironment(nil) let defined_functions = newTable[string, DefFuncs]() ExecutionContext( - worker: worker, + vars: env, builtin_functions: funcs, defined_functions: defined_functions, running: false, @@ -68,41 +47,31 @@ proc MakeExecutionContext*(funcs: ExecFuncs): ExecutionContext = proc ExecuteLines(ec: ExecutionContext, lines: seq[LightExpr]): LightInt -func GetVar(worker: LightWorker, variable: LightVariable): LightInt = - case variable: - 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 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 +func GetVar(env: Environment, variable: LightVariable): LightInt = + if hasKey(env.values, variable): + return env.values[variable] + + if env.parent == nil: + raise newException(ValueError, "Undefined variable: " & variable) + + return env.parent.GetVar(variable) + +func SetVar(env: Environment, variable: LightVariable, value: LightInt): LightInt = + if hasKey(env.values, variable): + env.values[variable] = value + value + + else: + if env.parent == nil: + raise newException(ValueError, "Undefined variable") + + env.parent.SetVar(variable, value) + +func NewVar(env: Environment, variable: LightVariable) = + if hasKey(env.values, variable): + raise newException(ValueError, "Reclaration of variable: " & variable) + + env.values[variable] = 0 proc EvalExpr(ec: ExecutionContext, exp: LightExpr): LightInt = case exp.kind: @@ -110,7 +79,11 @@ proc EvalExpr(ec: ExecutionContext, exp: LightExpr): LightInt = 0 of leVar: - GetVar(ec.worker, exp.var_name) + GetVar(ec.vars, exp.var_name) + + of leVarDef: + NewVar(ec.vars, exp.var_name) + 0 of leNumLit: exp.value @@ -124,7 +97,7 @@ proc EvalExpr(ec: ExecutionContext, exp: LightExpr): LightInt = of leAssign: let value = EvalExpr(ec, exp.expression) - SetVar(ec.worker, exp.variable, value) + SetVar(ec.vars, exp.variable, value) of leIf: let cond = EvalExpr(ec, exp.condition) @@ -162,23 +135,20 @@ proc EvalExpr(ec: ExecutionContext, exp: LightExpr): LightInt = for param in exp.params: args.add(EvalExpr(ec, param)) - var ind: int = 0 - var params: PContext + var new_env = MakeEnvironment(ec.vars) + var ind: int = 0 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] - + + new_env.NewVar(par) + discard new_env.SetVar(par, args[ind]) ind += 1 - ec.worker.param_stack.Push(params) + ec.vars = new_env let ret = ExecuteLines(ec, ec.defined_functions[exp.func_name].body) - discard ec.worker.param_stack.Pop() + ec.vars = new_env.parent ret else: diff --git a/src/lang/lexer.nim b/src/lang/lexer.nim index 9192dd8..989d06a 100644 --- a/src/lang/lexer.nim +++ b/src/lang/lexer.nim @@ -28,31 +28,13 @@ iterator Generate_tokens*(source: string): LightToken = continue if token.startsWith('$'): - let varString = token[1 .. ^1].toLowerAscii - var varName: LightVariable + let varName = token[1 .. ^1].toLowerAscii - if varString == "": + if varName == "": raise newException(IOError, "Expected variable name") - else: - 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.") - + yield LightToken(kind: ltVar, var_name: varName) - + elif token.startsWith('!'): let funcName = token[1..^1].toLowerAscii yield LightToken(kind: ltFunc, func_name: funcName) @@ -70,6 +52,8 @@ iterator Generate_tokens*(source: string): LightToken = yield LightToken(kind: ltNum, value: value.LightInt) + elif token == "var": + yield LightToken(kind: ltVarDef) elif token.toLowerAscii == "if": yield LightToken(kind: ltIf) elif token.toLowerAscii == "else": diff --git a/src/lang/parser.nim b/src/lang/parser.nim index 929e284..19be2e6 100644 --- a/src/lang/parser.nim +++ b/src/lang/parser.nim @@ -73,19 +73,36 @@ func NextExpr(tokens: Iter[LightToken], prev: LightExpr, stop_at: set[LightToken let next = tokens.NextExpr(LightExpr(kind: leNull), {ltRightParen}) tokens.Step() return tokens.NextExpr(next, stop_at) + + elif curr.kind == ltVarDef: + if tokens.Current.kind != ltVar: + raise newException(ValueError, "Expected variable name for variable declaration") + + let name = tokens.Current.var_name + + return LightExpr( + kind: leVarDef, + var_name: name + ) elif curr.kind == ltEq: + var variable: string = "" if prev.kind != leVar: - raise newException(ValueError, "Expected variable on the left of assignment operator") + if tokens.Previous(2).kind == ltVar: + variable = tokens.Previous(2).var_name + else: + raise newException(ValueError, "Expected variable on the left of assignment operator") + + let next = tokens.NextExpr(LightExpr(kind: leNull), stop_at) - else: - let next = tokens.NextExpr(LightExpr(kind: leNull), stop_at) + if variable == "": + variable = prev.var_name - return LightExpr( - kind: leAssign, - variable: prev.var_name, - expression: next - ) + return LightExpr( + kind: leAssign, + variable: variable, + expression: next + ) elif curr.kind == ltIf: let condition = tokens.NextExpr(LightExpr(kind: leNull), {ltBlockStart}) @@ -134,8 +151,6 @@ func NextExpr(tokens: Iter[LightToken], prev: LightExpr, stop_at: set[LightToken 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) diff --git a/src/lang/types/ast.nim b/src/lang/types/ast.nim index 11ffa94..b1d5e65 100644 --- a/src/lang/types/ast.nim +++ b/src/lang/types/ast.nim @@ -5,20 +5,21 @@ import ./tokens type LightExprType* = enum - leNull = 0, - leVar = 1, - leNumLit = 2, - leOp = 3, - leAssign = 4, - leIf = 5, - leWhile = 6, - leBreak = 7, - leFuncCall = 8, - leFuncDef = 9, + leNull, + leVar, + leVarDef, + leNumLit, + leOp, + leAssign, + leIf, + leWhile, + leBreak, + leFuncCall, + leFuncDef, LightExpr* = ref object case kind*: LightExprType - of leVar: + of leVar, leVarDef: var_name*: LightVariable of leNumLit: value*: LightInt @@ -53,6 +54,7 @@ func printExpr(exp: LightExpr, ind: int): string = let ts = strutils.repeat(" ", ind) ts & ( case exp.kind: + of leVarDef: "varDef[" & $exp.var_name & "]" of leVar: "var[" & $exp.var_name & "]" of leNumLit: "num[" & $exp.value & "]" of leOp: "op[" & $exp.operation & ", " & printExpr(exp.left, 0) & ", " & printExpr(exp.right, 0) & "]" diff --git a/src/lang/types/tokens.nim b/src/lang/types/tokens.nim index 2a9014a..5eb49b8 100644 --- a/src/lang/types/tokens.nim +++ b/src/lang/types/tokens.nim @@ -3,7 +3,7 @@ import ./types type LightTokenType* = enum ltNull, - ltVar, ltNum, + ltVar, ltNum, ltVarDef, ltExprDelim, ltLeftParen, ltRightParen, ltIf, ltElse, ltWhile, @@ -32,6 +32,7 @@ proc `$`*(token: LightToken): string = case token.kind: of ltNull: "NullToken" of ltVar: "VarToken[" & $token.var_name & "]" + of ltVarDef: "VarDefToken" of ltEq: "EqualsToken" of ltNum: "NumberToken[" & $token.value & "]" of ltExprDelim: "ExprDelimToken" diff --git a/src/lang/types/types.nim b/src/lang/types/types.nim index 487f478..688638f 100644 --- a/src/lang/types/types.nim +++ b/src/lang/types/types.nim @@ -1,9 +1,10 @@ type - LightVariable* = enum - 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 + #LightVariable* = enum + # 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 + LightVariable* = string LightOperation* = enum loAdd, loSub, loMul, loDiv, loMod, @@ -12,19 +13,19 @@ type 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" +#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" diff --git a/src/utils/iter.nim b/src/utils/iter.nim index 42b1966..89084c0 100644 --- a/src/utils/iter.nim +++ b/src/utils/iter.nim @@ -8,8 +8,8 @@ type proc CreateIter*[T](items: seq[T], empty: T): Iter[T] = Iter[T](curr: 0, list: items, length: items.len, empty: empty) -proc Step*[T](iter: Iter[T]) = - iter.curr += 1 +proc Step*[T](iter: Iter[T], off: int = 1) = + iter.curr += off func ReachedEnd*[T](iter: Iter[T]): bool = iter.curr >= iter.length @@ -20,15 +20,15 @@ proc Current*[T](iter: Iter[T]): T = return iter.list[iter.curr] -proc Previous*[T](iter: Iter[T]): T = - if iter.curr - 1 < 0 or iter.curr - 1 >= iter.length: +proc Previous*[T](iter: Iter[T], off: int = 1): T = + if iter.curr - off < 0 or iter.curr - off >= iter.length: return iter.empty - return iter.list[iter.curr - 1] + return iter.list[iter.curr - off] -proc Next*[T](iter: Iter[T]): T = - if iter.curr + 1 < 0 or iter.curr + 1 >= iter.length: +proc Next*[T](iter: Iter[T], off: int = 1): T = + if iter.curr + off < 0 or iter.curr + off >= iter.length: return iter.empty - return iter.list[iter.curr + 1] + return iter.list[iter.curr + off]