From 3b4c500a3af203367b76002798d7158c2460be67 Mon Sep 17 00:00:00 2001 From: Jairus Date: Tue, 12 Nov 2024 09:28:05 -0500 Subject: [PATCH] push --- src/ast/nodes/BinaryExpression.ts | 1 + src/ast/nodes/Expression.ts | 11 ++++++++++- src/parser/index.ts | 25 ++++++++++++++++++++++--- src/scripts/fib.zp | 23 ++++++++++++----------- src/test.ts | 29 ++++++++++++----------------- src/tokenizer/token.ts | 1 + src/tokenizer/util.ts | 9 +++++++++ 7 files changed, 67 insertions(+), 32 deletions(-) diff --git a/src/ast/nodes/BinaryExpression.ts b/src/ast/nodes/BinaryExpression.ts index c562c50..1a4ce07 100644 --- a/src/ast/nodes/BinaryExpression.ts +++ b/src/ast/nodes/BinaryExpression.ts @@ -29,4 +29,5 @@ export enum Operator { Equals = "=", EqualsEquals = "==", EqualsEqualsEquals = "===", + LessThanEquals = "<=" } diff --git a/src/ast/nodes/Expression.ts b/src/ast/nodes/Expression.ts index a7a4fc5..6e217e2 100644 --- a/src/ast/nodes/Expression.ts +++ b/src/ast/nodes/Expression.ts @@ -2,5 +2,14 @@ import { Range } from "../Range"; export class Expression { public nameOf: string = "Expression"; - public range: Range = new Range(-1, -1, -1); + public range: Range = new Range( + { + line: -1, + column: -1 + }, + { + line: -1, + column: -1 + } + ); } diff --git a/src/parser/index.ts b/src/parser/index.ts index 930996d..343c1fd 100644 --- a/src/parser/index.ts +++ b/src/parser/index.ts @@ -99,10 +99,10 @@ export class Parser { parseExpression(scope: Scope, besides: string | null = null): Expression | null { let express: Expression | null = null; const state = this.source.tokenizer.createState(); - if (besides !== "CallExpression" && (express = this.parseCallExpression(scope))) return express; - state.resume(); if (besides !== "BinaryExpression" && (express = this.parseBinaryExpression(scope))) return express; state.resume(); + if (besides !== "CallExpression" && (express = this.parseCallExpression(scope))) return express; + state.resume(); if (besides !== "NumberLiteral" && (express = this.parseNumberLiteral(scope))) return express; state.resume(); if (besides !== "StringLiteral" && (express = this.parseStringLiteral(scope))) return express; @@ -557,6 +557,7 @@ export class Parser { } parseCallExpression(scope: Scope): CallExpression | null { const calling = this.source.tokenizer.getToken(); + if (!isIdentifier(calling)) return null; const leftParen = this.source.tokenizer.getToken(); if (leftParen.text !== "(") return null; const args: Expression[] = []; @@ -636,8 +637,25 @@ export class Parser { ); return node; } + parseBinaryExpressionLeft(scope: Scope) { + const state = this.source.tokenizer.createState(); + let left: Expression | null; + if (left = this.parseCallExpression(scope)) return left; + state.resume(); + if (left = this.parseNumberLiteral(scope)) return left; + state.resume(); + if (left = this.parseIdentifierExpression(scope)) return left; + state.resume(); + if (left = this.parseStringLiteral(scope)) return left; + state.resume(); + if (left = this.parseBooleanLiteral(scope)) return left; + state.resume(); + if (left = this.parseParenthesizedExpression(scope)) return left; + state.resume() + return null; + } parseBinaryExpression(scope: Scope): BinaryExpression | null { - let left: Expression | null = this.parseIdentifierExpression(scope) || this.parseNumberLiteral(scope) || this.parseIdentifierExpression(scope) || this.parseStringLiteral(scope) || this.parseBooleanLiteral(scope) || this.parseParenthesizedExpression(scope); + let left: Expression | null = this.parseBinaryExpressionLeft(scope); if (!left) return null; const op = tokenToOp(this.source.tokenizer.getToken()); let right: Expression | null = this.parseExpression(scope); @@ -779,5 +797,6 @@ export function tokenToOp(tok: TokenData): Operator | null { if (tok.token === Token.Equals) return Operator.Equals; if (tok.token === Token.EqualsEquals) return Operator.EqualsEquals; if (tok.token === Token.EqualsEqualsEquals) return Operator.EqualsEqualsEquals; + if (tok.token === Token.LessThanEquals) return Operator.LessThanEquals; return null; } diff --git a/src/scripts/fib.zp b/src/scripts/fib.zp index 2f4619f..ca5c446 100644 --- a/src/scripts/fib.zp +++ b/src/scripts/fib.zp @@ -1,14 +1,15 @@ -#[export] +import "std:io" + fn fib(n: i32) -> i32 { - i32 a = 0 - i32 b = 1 - if (n > 0) { - while (--n) { - i32 t = a + b - a = b - b = t + if n <= 1 { + rt n + } else { + rt fib(n - 1) + fib(n - 2) } - return b - } - return a } + +#[export] +fn main() -> void { + i32 result = fib(7) + print(result) +} \ No newline at end of file diff --git a/src/test.ts b/src/test.ts index 49247f2..9feb1f3 100644 --- a/src/test.ts +++ b/src/test.ts @@ -6,11 +6,12 @@ import { Generator } from "./generator"; import { Scope } from "./checker/scope/Scope"; import { Source, SourceKind } from "./ast/Source"; import { Program } from "./ast/Program"; +import { SyntaxColors } from "./formatter/syntaxcolors"; const start = Date.now(); const program = new Program([ new Source( - "std:io/print", + "std:io", ` #[extern]: env #[export] @@ -21,21 +22,21 @@ const program = new Program([ new Source( "test.zp", ` - import "std:io/print" +import "std:io" - fn factorial(n: i32) -> i32 { - if n == 0 { - rt 1 +fn fib(n: i32) -> i32 { + if n <= 1 { + rt n } else { - rt n * factorial(n - 1) + rt fib(n - 1) + fib(n - 2) } - } +} - #[export] - fn main() -> void { - i32 result = factorial(5) +#[export] +fn main() -> void { + i32 result = fib(16) print(result) - } +} `, SourceKind.UserEntry ) @@ -48,9 +49,3 @@ console.dir(source.topLevelStatements, { depth: 1 }); // console.log(new Program([new Source("test.zp", 'import "std:io/print"', SourceKind.UserEntry)]).entry.parser.parseImportDeclaration(new Scope())) const transpiled = Formatter.from(source); console.log("\n" + transpiled.trim()); - -// const generator = new Generator(); -// generator.parseFn(program.topLevelStatements[1]) -// console.log("WAT:\n" + generator.toWat()); - -// writeFileSync("./test.ts", transpiled); diff --git a/src/tokenizer/token.ts b/src/tokenizer/token.ts index e013c1a..2c92abc 100644 --- a/src/tokenizer/token.ts +++ b/src/tokenizer/token.ts @@ -31,6 +31,7 @@ export enum Token { // COMPARISIONS GreaterThan, // > LessThan, // < + LessThanEquals, // <= // SYMBOLS Pound, // # // UTILITY diff --git a/src/tokenizer/util.ts b/src/tokenizer/util.ts index ad90e40..4382c18 100644 --- a/src/tokenizer/util.ts +++ b/src/tokenizer/util.ts @@ -21,6 +21,15 @@ export function isPunctuation( } else if (text.startsWith("=", position.current)) { position.current++; return new TokenData(Token.Equals, "=", position.toRange()); + } else if (text.startsWith(":=", position.current)) { + position.current += 2; + return new TokenData(Token.ColonEquals, ":=", position.toRange()); + } else if (text.startsWith("?=", position.current)) { + position.current += 2; + return new TokenData(Token.QuestionEquals, "?=", position.toRange()); + } else if (text.startsWith("<=", position.current)) { + position.current += 2; + return new TokenData(Token.LessThanEquals, "<=", position.toRange()); } else if (text.startsWith("?", position.current)) { position.current++; return new TokenData(Token.Question, "?", position.toRange());