From fcc617dbf4d008612e5df08583445f307f9552ba Mon Sep 17 00:00:00 2001
From: "W. Cho" <wcho.dev@gmail.com>
Date: Thu, 21 Dec 2023 18:42:54 +0900
Subject: [PATCH] fix token eating logic while parsing

---
 src/parser/index.test.ts | 38 ++++++++++++++++++++++++++++++++++++++
 src/parser/index.ts      | 11 ++++++++---
 2 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/src/parser/index.test.ts b/src/parser/index.test.ts
index 4aab415..3dbd0a3 100644
--- a/src/parser/index.test.ts
+++ b/src/parser/index.test.ts
@@ -1015,4 +1015,42 @@ describe("parseProgram()", () => {
 
     it.each(cases)("parse $name", testParsing);
   });
+
+  describe("complex expression", () => {
+    const cases: { name: string, input: string, expected: Program }[] = [
+      {
+        name: "assignment and arithmetic expression",
+        input: "변수1 = 1  ((변수1 + 변수1) * 변수1)",
+        expected: {
+          type: "program",
+          statements: [
+            {
+              type: "expression statement",
+              expression: {
+                type: "assignment",
+                left: { type: "identifier", value: "변수1" },
+                right: { type: "number node", value: 1 },
+              },
+            },
+            {
+              type: "expression statement",
+              expression: {
+                type: "infix expression",
+                infix: "*",
+                left: {
+                  type: "infix expression",
+                  infix: "+",
+                  left: { type: "identifier", value: "변수1" },
+                  right: { type: "identifier", value: "변수1" },
+                },
+                right: { type: "identifier", value: "변수1" },
+              },
+            },
+          ],
+        },
+      },
+    ];
+
+    it.each(cases)("parse $name", testParsing);
+  });
 });
diff --git a/src/parser/index.ts b/src/parser/index.ts
index a6f767c..c23626e 100644
--- a/src/parser/index.ts
+++ b/src/parser/index.ts
@@ -278,13 +278,15 @@ export default class Parser {
   }
 
   private parseInfixExpression(left: Expression): Expression | null {
+    // note: do not eat token and just return null if not parsable
     const token = this.buffer.read();
-    this.buffer.next(); // eat infix token
 
     if (token.type === "group delimiter" && token.value === "(") {
       if (left.type !== "function expression" && left.type !== "identifier") {
-        throw new Error(`expected function expression or identifier, but received ${left.type}`);
+        return null;
       }
+
+      this.buffer.next(); // eat infix token
       return this.parseCall(left);
     }
 
@@ -294,7 +296,9 @@ export default class Parser {
 
     const infix = token.value;
     if (infix === "=" && left.type === "identifier") {
-      return this.parseAssignment(left);
+      this.buffer.next(); // eat infix token
+      const a=  this.parseAssignment(left);
+      return a;
     }
     if (
       infix === "+" ||
@@ -308,6 +312,7 @@ export default class Parser {
       infix === ">=" ||
       infix === "<="
     ) {
+      this.buffer.next(); // eat infix token
       return this.parseArithmeticInfixExpression(left, infix);
     }
     return null;