arbitrary variable names; variable scopes; bug fixes
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 18 Dec 2018 06:57:33 +0000 (00:57 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 18 Dec 2018 06:57:33 +0000 (00:57 -0600)
19 files changed:
christmas_proj
christmas_proj.nimble
data/progs/avg.lgt [deleted file]
data/progs/first.lgt [deleted file]
data/progs/gol.lgt [deleted file]
data/progs/gol.light [new file with mode: 0644]
data/progs/maze.lgt [deleted file]
data/progs/maze.light [new file with mode: 0644]
data/progs/new_syntax.light
data/progs/sorts.light [new file with mode: 0644]
src/board/board.nim
src/christmas_proj.nim
src/lang/executer.nim
src/lang/lexer.nim
src/lang/parser.nim
src/lang/types/ast.nim
src/lang/types/tokens.nim
src/lang/types/types.nim
src/utils/iter.nim

index b4796ba8496bdea29c8e7fe1c05f35c0ddce77f4..1c1efbc3006942bbaa37397916b9042fa4ed97a6 100755 (executable)
Binary files a/christmas_proj and b/christmas_proj differ
index c147fcdcaa247908cbcbe3b54bfd769f45f62103..c935d1f61ebc741b6cc1c987431bcc5740fe861a 100644 (file)
@@ -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 (file)
index 3128585..0000000
+++ /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 (file)
index 748ee79..0000000
+++ /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 (file)
index 40c1fbf..0000000
+++ /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 (file)
index 0000000..4c1ddec
--- /dev/null
@@ -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 (file)
index f450a50..0000000
+++ /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 (file)
index 0000000..40858b7
--- /dev/null
@@ -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()
index 48ff7a17aea08f1db7340dccbd2546a253da2e3f..101ad5abe5d230bc906d8b1011fbd1dd22079718 100644 (file)
@@ -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 (file)
index 0000000..0725b02
--- /dev/null
@@ -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)
index 3f481446d1758bf36749c72c938eab43dbc1e3e5..0f0617c0009073dbc3d89abffa2dbfb4d8d64c7a 100644 (file)
@@ -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)
index da147177467507d604f7fb4826e1a070d2e32798..2217b1162e1d38922ac62c59e5817eb49581061b 100644 (file)
@@ -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()
     ),
index cb76310557e5d80ff4acc7f111f92f9e63603373..50061fc6dac47c2eea951370ad6f0dc1c44604c5 100644 (file)
@@ -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:
index 9192dd8e9d7f098b58d2712d0663044a10d07e3f..989d06a22d4da761f27cf153dda8c92e943dc666 100644 (file)
@@ -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":
index 929e2844d62c46b0061d3eda747905f8578e040e..19be2e6e60dca222142b13932a16fb3191066551 100644 (file)
@@ -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)
 
index 11ffa946dd0873a523be85b14f041e7cddb801e2..b1d5e653ca2debe3101aa6ef07829773c81a1fb4 100644 (file)
@@ -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) & "]"
index 2a9014a71a19e885485005a2dee6099680d1befb..5eb49b81e41ec409bdd1249f9f54747265b28a1d 100644 (file)
@@ -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"
index 487f478309b2d285dfc95ebffb0c97a1c91af074..688638f5b5a7488d0a8c9287d8c3c5b038838878 100644 (file)
@@ -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"
index 42b196645210d10346e6995d27167a0dcbadf27f..89084c092856ec3ff107728c04eb4a46d08c8c71 100644 (file)
@@ -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]