From 1fc116f2fee6e99318a284ceb0a7655d9e8242b4 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Sun, 1 Feb 2026 00:18:43 -0700 Subject: [PATCH] parsing function application --- src/main.ts | 2 +- src/parser.ts | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/main.ts b/src/main.ts index 5b875ad..66d3ac1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -24,7 +24,7 @@ console.log(tokenize(str)); // const tokens2 = tokenize("let x = (y) => 5 + y in x(3)"); // const tokens2 = tokenize("let x = 5 in x * 4"); // const tokens2 = tokenize("(x, y) => x + y"); -const tokens2 = tokenize('[1, 2, 3]'); +const tokens2 = tokenize('map double [1, 2, 3]'); const p2 = new Parser(tokens2); const ast3 = p2.parse(); console.log(ast3); diff --git a/src/parser.ts b/src/parser.ts index 932e756..bc955ef 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -52,17 +52,29 @@ export class Parser { } } + private canStartPrimary(): boolean { + const kind = this.current().kind; + return kind === 'ident' || kind === 'type-ident' || + kind === 'int' || kind === 'float' || kind === 'string' || + kind === 'open-paren' || kind === 'open-bracket' || + kind === 'open-brace'; + } + parse(): AST { return this.parseExpression(); } private parseExpression(): AST { - let left = this.parsePrimary(); + return this.parseInfix(); + } + + private parseInfix(): AST { + let left = this.parseApplication(); while (this.isInfixOp()) { const opToken = this.advance(); const opName = this.tokenToOpName(opToken); - const right = this.parsePrimary(); + const right = this.parseApplication(); left = { kind: 'apply', @@ -74,6 +86,17 @@ export class Parser { return left; } + private parseApplication(): AST { + let func = this.parsePrimary(); + + while (this.canStartPrimary()) { + const arg = this.parsePrimary(); + func = { kind: 'apply', func, args: [arg] }; + } + + return func; + } + private parsePrimary(): AST { const token = this.current(); @@ -145,6 +168,11 @@ export class Parser { return { kind: 'variable', name: token.value }; } + if (token.kind === 'type-ident') { + this.advance(); + return { kind: 'constructor', name: token.value }; + } + throw new Error(`Unexpected token: ${token.kind}`); }