From 1788fab2081d35ab4ad015fa7da4a9f979fddc0e Mon Sep 17 00:00:00 2001 From: Paulyn <87922888+JakeOJeff@users.noreply.github.com> Date: Sun, 23 Nov 2025 19:07:38 +0530 Subject: [PATCH 1/9] Setting Nodes and Token Types --- compiler/parser.rb | 2 ++ compiler/tokenizer.rb | 2 ++ 2 files changed, 4 insertions(+) diff --git a/compiler/parser.rb b/compiler/parser.rb index 76680e4..29a7ded 100644 --- a/compiler/parser.rb +++ b/compiler/parser.rb @@ -11,6 +11,8 @@ PrintNode = Struct.new(:args) ReturnNode = Struct.new(:statement) AndOrListNode = Struct.new(:items) +SwitchNode = Struct.new(:value, :cases) +CaseNode = Struct.new(:match, :body) LoveCallNode = Struct.new(:namespace, :name, :args) diff --git a/compiler/tokenizer.rb b/compiler/tokenizer.rb index 8fb0f47..4327063 100644 --- a/compiler/tokenizer.rb +++ b/compiler/tokenizer.rb @@ -12,6 +12,8 @@ class Tokenizer [:return, /\breturn\b/], [:or, /\bor\b/], [:and, /\band\b/], + [:switch, /\bswitch\b/], + [:to, /\bto\b/] #love [:lgraphics, /-G:/], From f6794e454b59c8dde1cb49a7f48bc9c095012713 Mon Sep 17 00:00:00 2001 From: Paulyn <87922888+JakeOJeff@users.noreply.github.com> Date: Sun, 23 Nov 2025 19:12:57 +0530 Subject: [PATCH 2/9] Setting switch parser --- compiler/parser.rb | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/compiler/parser.rb b/compiler/parser.rb index 29a7ded..c1b9a02 100644 --- a/compiler/parser.rb +++ b/compiler/parser.rb @@ -131,6 +131,32 @@ def parse_while WhileNode.new(statement, body) end + def parse_switch + consume(:switch) + value = parse_expr + skip_newlines + + cases = [] + + while peek(:to) + consume(:to) + match = parse_expr + skip_newlines + + body = [] + + until peek(:to) || peek(:end) + body << parse_statement + skip_newlines + end + + cases << CaseNode.new(match, body) + end + + consume(:end) + SwitchNode.new(value, cases) + end + def parse_print consume(:print) @@ -150,6 +176,8 @@ def parse_statement parse_if elsif peek(:while) parse_while + elsif peek(:switch) + parse_switch elsif peek(:print) parse_print elsif peek(:local) From 4619ec5b44043f1b1f5fd232619c851aedd912b9 Mon Sep 17 00:00:00 2001 From: Paulyn <87922888+JakeOJeff@users.noreply.github.com> Date: Sun, 23 Nov 2025 20:43:27 +0530 Subject: [PATCH 3/9] Setting Code generator --- compiler/codegen.rb | 18 ++++++++++++++++++ examples/main.lat | 8 ++++++++ 2 files changed, 26 insertions(+) diff --git a/compiler/codegen.rb b/compiler/codegen.rb index 5a3a141..5060f22 100644 --- a/compiler/codegen.rb +++ b/compiler/codegen.rb @@ -44,6 +44,24 @@ def generate(node) generate(node.statement), body_code ] + + when SwitchNode + compiled = "" + node.cases.each_with_index do |c, i| + if i == 0 + compiled << "if #{generate(c.match)} == #{generate(node.value)} then\n" + else + compiled << "elseif #{generate(c.match)} == #{generate(node.value)} then\n" + end + + body_code = c.body.map { |b| generate(b) }.join("\n") + compiled << " #{body_code}\n" + + end + compiled << "end" + compiled + + when CallNode "%s(%s)" % [ node.name, diff --git a/examples/main.lat b/examples/main.lat index 353af14..6fc98f5 100644 --- a/examples/main.lat +++ b/examples/main.lat @@ -16,5 +16,13 @@ when (true) done +switch score + t 10 + print("perfect") + t 5 + print("ok) + +done + print(coins) \ No newline at end of file From 5f969aba9604318312d24889933edefd73bbddcb Mon Sep 17 00:00:00 2001 From: Paulyn <87922888+JakeOJeff@users.noreply.github.com> Date: Sun, 23 Nov 2025 21:37:19 +0530 Subject: [PATCH 4/9] Fixed bugs --- compiler/tokenizer.rb | 4 ++-- examples/main.lat | 6 +++--- test.lua | 5 +++++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/compiler/tokenizer.rb b/compiler/tokenizer.rb index 4327063..6c8e2d1 100644 --- a/compiler/tokenizer.rb +++ b/compiler/tokenizer.rb @@ -13,7 +13,7 @@ class Tokenizer [:or, /\bor\b/], [:and, /\band\b/], [:switch, /\bswitch\b/], - [:to, /\bto\b/] + [:to, /\bto\b/], #love [:lgraphics, /-G:/], @@ -40,7 +40,7 @@ class Tokenizer [:greater, />/], [:lesser, /=/], - [:lequal, /<=/] + [:lequal, /<=/], [:equal, /=/], [:divide, /\//], [:multiply, /\*/], diff --git a/examples/main.lat b/examples/main.lat index 6fc98f5..67d19fd 100644 --- a/examples/main.lat +++ b/examples/main.lat @@ -17,10 +17,10 @@ when (true) done switch score - t 10 + to 10 print("perfect") - t 5 - print("ok) + to 5 + print("ok") done diff --git a/test.lua b/test.lua index 705d96b..234644f 100644 --- a/test.lua +++ b/test.lua @@ -10,5 +10,10 @@ function incrementCoin(externalMultiplier) end while true do +end +if 10 == score then + print("perfect") +elseif 5 == score then + print("ok") end print(coins) \ No newline at end of file From 2853216501be2ccb933e9482f3e3e9b1a38bf666 Mon Sep 17 00:00:00 2001 From: Paulyn <87922888+JakeOJeff@users.noreply.github.com> Date: Sun, 23 Nov 2025 22:01:46 +0530 Subject: [PATCH 5/9] Rewriting If Statements --- compiler/parser.rb | 56 +++++++++++++++++++++++++++++++------------ compiler/tokenizer.rb | 2 ++ 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/compiler/parser.rb b/compiler/parser.rb index c1b9a02..87ca751 100644 --- a/compiler/parser.rb +++ b/compiler/parser.rb @@ -1,5 +1,5 @@ DefNode = Struct.new(:name, :args, :body) -IfNode = Struct.new(:statement, :body) +IfNode = Struct.new(:statement, :cases) WhileNode = Struct.new(:statement, :body) IntegerNode = Struct.new(:value) StringNode = Struct.new(:value) @@ -88,26 +88,52 @@ def parse_return end def parse_if - consume(:if) - if peek(:oparen) - consume(:oparen) - statement = parse_expr - consume(:cparen) - else - statement = parse_expr - end + consume(:if) + condition = parse_expr skip_newlines - body = [] - - until peek(:end) - body << parse_statement + if_body = [] + while !peek(:elif) && !peek(:else) && !peek(:end) + if_body << parse_statement skip_newlines end - consume(:end) - IfNode.new(statement, body) + + + elif_blocks = [] + while peek(:elif) + consume(:elif) + elif_condition = parse_expr + skip_newlines + + elif_body = [] + while !peek(:elif) && !peek(:else) && !peek(:end) + elif_body << parse_statement + skip_newlines + end + + + end + # consume(:if) + + # if peek(:oparen) + # consume(:oparen) + # statement = parse_expr + # consume(:cparen) + # else + # statement = parse_expr + # end + # skip_newlines + # body = [] + + # until peek(:elif) peek(:end) + # body << parse_statement + # skip_newlines + # end + # consume(:end) + # IfNode.new(statement, body) + def parse_while consume(:while) diff --git a/compiler/tokenizer.rb b/compiler/tokenizer.rb index 6c8e2d1..8faac0e 100644 --- a/compiler/tokenizer.rb +++ b/compiler/tokenizer.rb @@ -7,6 +7,8 @@ class Tokenizer [:def, /\bcall\b/], [:end, /\bdone\b/], [:if, /\bif\b/], + [:elif, /\belif\b/], + [:else, /\belse\b/], [:while, /\bwhen\b/], [:print, /\bprint\b/], [:return, /\breturn\b/], From 38b9e40992aa05ed4814471700c5c8523bfee24b Mon Sep 17 00:00:00 2001 From: Paulyn <87922888+JakeOJeff@users.noreply.github.com> Date: Sun, 23 Nov 2025 22:06:38 +0530 Subject: [PATCH 6/9] Fixing parser for if else nodes --- compiler/parser.rb | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/compiler/parser.rb b/compiler/parser.rb index 87ca751..d56092b 100644 --- a/compiler/parser.rb +++ b/compiler/parser.rb @@ -1,5 +1,8 @@ DefNode = Struct.new(:name, :args, :body) -IfNode = Struct.new(:statement, :cases) + +IfNode = Struct.new(:condition, :body, :elif_blocks, :else_body) +ElifBlock = Struct.new(:condition, :body) + WhileNode = Struct.new(:statement, :body) IntegerNode = Struct.new(:value) StringNode = Struct.new(:value) @@ -111,8 +114,27 @@ def parse_if skip_newlines end - + elif_blocks << ElifBlock.new(elif_condition, elif_body) + + end + + else_body = nil + if peek(:else) + consume(:else) + skip_newlines + + else_body = [] + while !peek(:end) + else_body << parse_statement + skip_newlines + end + end + + consume(:end) + + IfNode.new(condition, if_body, elif_blocks, else_body) + end # consume(:if) From 7190bd85dd5461568bfc3895c28f03bd6395e5d4 Mon Sep 17 00:00:00 2001 From: Paulyn <87922888+JakeOJeff@users.noreply.github.com> Date: Sun, 23 Nov 2025 23:10:17 +0530 Subject: [PATCH 7/9] Fixing If Nodes --- compiler/codegen.rb | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/compiler/codegen.rb b/compiler/codegen.rb index 5060f22..deb8066 100644 --- a/compiler/codegen.rb +++ b/compiler/codegen.rb @@ -20,17 +20,24 @@ def generate(node) ] when IfNode - body_code = - if node.body.is_a?(Array) - node.body.map { |n| generate (n) }.join("\n") - else - generate(node.body) + compiled = "" + + first = node.statement + compiled << "if #{generate(first)} then\n" + compiled << node.body.map { |n| generate (n) }.join("\n") + + node.elif_blocks[1..]&.each do |c| + compiled << "elseif #{generate(c.condition)} then\n" + compiled << c.body.map { |n| generate (n) }.join("\n") end - "if %s then \n %s \nend" % [ - generate(node.statement), - body_code - ] + if node.else_body + compiled << "else\n" + compiled << c.else_body.map { |n| generate (n) }.join("\n") + end + + compiled << "end" + compiled when WhileNode body_code = From e1bd4ed18958b772d3015ee12ff4ba778b250019 Mon Sep 17 00:00:00 2001 From: Paulyn <87922888+JakeOJeff@users.noreply.github.com> Date: Sun, 23 Nov 2025 23:14:32 +0530 Subject: [PATCH 8/9] Fixed the else and Elif Statements --- compiler/codegen.rb | 6 +++--- examples/main.lat | 2 ++ test.lua | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/compiler/codegen.rb b/compiler/codegen.rb index deb8066..47710a1 100644 --- a/compiler/codegen.rb +++ b/compiler/codegen.rb @@ -22,18 +22,18 @@ def generate(node) when IfNode compiled = "" - first = node.statement + first = node.condition compiled << "if #{generate(first)} then\n" compiled << node.body.map { |n| generate (n) }.join("\n") - node.elif_blocks[1..]&.each do |c| + node.elif_blocks.each do |c| compiled << "elseif #{generate(c.condition)} then\n" compiled << c.body.map { |n| generate (n) }.join("\n") end if node.else_body compiled << "else\n" - compiled << c.else_body.map { |n| generate (n) }.join("\n") + compiled << node.else_body.map { |n| generate (n) }.join("\n") end compiled << "end" diff --git a/examples/main.lat b/examples/main.lat index 67d19fd..67a41fb 100644 --- a/examples/main.lat +++ b/examples/main.lat @@ -4,6 +4,8 @@ nat multiplier = 2 if (-K:isDown("space")) incrementCoin(3) +elif (-K:isDown("w")) + incrementCoin(3) done diff --git a/test.lua b/test.lua index 234644f..a49be60 100644 --- a/test.lua +++ b/test.lua @@ -1,9 +1,9 @@ local coins = 250 local incrementVal = 20 local multiplier = 2 -if love.keyboard.isDown("space") then - incrementCoin(3) -end +if love.keyboard.isDown("space") then +incrementCoin(3)elseif love.keyboard.isDown("w") then +incrementCoin(3)end function incrementCoin(externalMultiplier) coins = (coins + ((incrementVal * multiplier) * externalMultiplier)) return coins From 1f42dadb9f3a8b97e004b274ccdc76f89db7a4cc Mon Sep 17 00:00:00 2001 From: Paulyn <87922888+JakeOJeff@users.noreply.github.com> Date: Sun, 23 Nov 2025 23:16:32 +0530 Subject: [PATCH 9/9] Fixing NewLines for IfElseStatements --- compiler/codegen.rb | 6 +++--- test.lua | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/compiler/codegen.rb b/compiler/codegen.rb index 47710a1..97bfe54 100644 --- a/compiler/codegen.rb +++ b/compiler/codegen.rb @@ -27,16 +27,16 @@ def generate(node) compiled << node.body.map { |n| generate (n) }.join("\n") node.elif_blocks.each do |c| - compiled << "elseif #{generate(c.condition)} then\n" + compiled << "\nelseif #{generate(c.condition)} then\n" compiled << c.body.map { |n| generate (n) }.join("\n") end if node.else_body - compiled << "else\n" + compiled << "\nelse\n" compiled << node.else_body.map { |n| generate (n) }.join("\n") end - compiled << "end" + compiled << "\nend" compiled when WhileNode diff --git a/test.lua b/test.lua index a49be60..f019ff6 100644 --- a/test.lua +++ b/test.lua @@ -2,8 +2,10 @@ local coins = 250 local incrementVal = 20 local multiplier = 2 if love.keyboard.isDown("space") then -incrementCoin(3)elseif love.keyboard.isDown("w") then -incrementCoin(3)end +incrementCoin(3) +elseif love.keyboard.isDown("w") then +incrementCoin(3) +end function incrementCoin(externalMultiplier) coins = (coins + ((incrementVal * multiplier) * externalMultiplier)) return coins