Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
JairusSW committed Jan 26, 2024
1 parent 16ff582 commit 8ebbe1f
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 16 deletions.
14 changes: 14 additions & 0 deletions docs/specification/Exports.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Exports

## Design

Imports allow top-level-statements exported to other files.

The syntax in Zep is like so

```rust
#[export]: alias-name
fn add(a: i32, b: i32) -> i32 {
rt a + b
}
```
21 changes: 21 additions & 0 deletions docs/specification/Imports.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Imports

## Design

Imports allow top-level-statements to be accessed from other files.

The syntax in Zep is like so

```rust
import "file.zp" as foo
```

```rust
import "file.zp" as { foo, bar, baz }

foo();
bar();
baz();
```

If no `as` option is supplied, the exports are attached to the namespace of the file's name.
24 changes: 24 additions & 0 deletions docs/specification/Loops.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Loops

## Design


```rust
#[extern]: env.print
fn print(data: i32) -> none

#[export]: main
fn main() -> none {
print(5)

for i in 0..5 {
print(i)
}

let numbers = [6, 7, 8, 9, 10]

for num in numbers {
print(num)
}
}
```
10 changes: 10 additions & 0 deletions src/ast/nodes/BooleanLiteral.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Expression } from "./Expression.js";

export class BooleanLiteral extends Expression {
public nameOf: string = "BooleanLiteral";
constructor(
public value: boolean
) {
super();
}
}
14 changes: 14 additions & 0 deletions src/ast/nodes/IfStatement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { BlockExpression } from "./BlockExpression";
import { Expression } from "./Expression.js";
import { Statement } from "./Statement.js";

export class IfStatement extends Statement {
public nameOf: string = "IfStatement";
public condition: Expression;
public block: BlockExpression;
constructor(condition: Expression, block: BlockExpression) {
super();
this.condition = condition;
this.block = block;
}
}
2 changes: 1 addition & 1 deletion src/generator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class Generator {
public module: w.Module = new w.Module();
public segments: w.MemorySegment[] = [];
constructor() { }
parseProgram(program: Program): none {
parseProgram(program: Program): void {
for (const topStmt of program.topLevelStatements) {
if (topStmt instanceof FunctionImport) {
this.parseFnImport(topStmt);
Expand Down
48 changes: 39 additions & 9 deletions src/parser/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ import { NumberLiteral } from "../ast/nodes/NumberLiteral.js";
import { FunctionImport } from "../ast/nodes/FunctionImport.js";
import { ModifierExpression } from "../ast/nodes/ModifierExpression.js";
import { ReferenceExpression } from "../ast/nodes/ReferenceExpression.js";
import { ErrorTypes, TokenMismatchError } from "../error/error.js";
import { TokenMismatchError } from "../error/error.js";
import { Range } from "../ast/Range.js";
import { Token } from "../tokenizer/token.js";
import { TokenData } from "../tokenizer/tokendata.js";
import { CallExpression } from "../ast/nodes/CallExpression.js";
import { IfStatement } from "../ast/nodes/IfStatement.js";
import { BooleanLiteral } from "../ast/nodes/BooleanLiteral.js";

export class Parser {
public program: Program = new Program("test.zp");
Expand All @@ -44,7 +46,9 @@ export class Parser {
this.tokenizer.resumeState();
if ((node = this.parseFunctionDeclaration(scope))) return node;
this.tokenizer.resumeState();
if ((node = this.parseReturnStatement())) return node;
if ((node = this.parseReturnStatement(scope))) return node;
this.tokenizer.resumeState();
if ((node = this.parseIfStatement(scope))) return node;
this.tokenizer.resumeState();
return null;
}
Expand All @@ -54,6 +58,8 @@ export class Parser {
this.tokenizer.resumeState();
if ((express = this.parseStringLiteral(scope))) return express;
this.tokenizer.resumeState();
if ((express = this.parseBooleanLiteral(scope))) return express;
this.tokenizer.resumeState();
if ((express = this.parseBinaryExpression(scope))) return express;
this.tokenizer.resumeState();
if ((express = this.parseReferenceExpression(scope))) return express;
Expand Down Expand Up @@ -102,6 +108,21 @@ export class Parser {
scope.add(name.text, node);
return node;
}
parseIfStatement(
scope: Scope = this.program.globalScope,
): IfStatement | null {
this.tokenizer.pauseState();
if (this.tokenizer.getToken().text !== "if") return null;
if (this.tokenizer.getToken().text !== "(") return null;
const condition = this.parseBooleanLiteral();
if (this.tokenizer.getToken().text !== ")") return null;
if (!condition) return null;
const block = this.parseBlockExpression();
if (!block) return null;

const node = new IfStatement(condition, block);
return node;
}
parseModifierExpression(
scope: Scope = this.program.globalScope,
): ModifierExpression | null {
Expand Down Expand Up @@ -139,7 +160,7 @@ export class Parser {
return null;
}
const content: TokenData[] = [contentFirstToken];
while (true) {
/*while (true) {
const token = this.tokenizer.getToken();
if (
contentFirstToken.range.line < token.range.line ||
Expand All @@ -150,7 +171,7 @@ export class Parser {
}
this.tokenizer.pauseState();
content.push(token);
}
}*/
const contentId = new Identifier(
content.map((v) => v.text).join(""),
new Range(
Expand All @@ -171,12 +192,12 @@ export class Parser {
): FunctionDeclaration | null {
this.tokenizer.pauseState();

let exported = true;
let exported = false;

const exp = this.tokenizer.getToken();
if (!isIdentifier(exp)) return null;
if (exp.text !== "export") exported = false;
const fn = exported ? this.tokenizer.getToken() : exp;
const exp = this.parseModifierExpression();
if (!exp) this.tokenizer.resumeState();
else if (exp.tag.data == "export") exported = true;
const fn = this.tokenizer.getToken();
if (!isIdentifier(fn) || fn.text !== "fn") return null;

const name = this.tokenizer.getToken();
Expand Down Expand Up @@ -479,6 +500,15 @@ export class Parser {
if (!isString(num)) return null;
return new StringLiteral(num.text);
}
parseBooleanLiteral(
scope: Scope = this.program.globalScope,
): BooleanLiteral | null {
this.tokenizer.pauseState();
const value = this.tokenizer.getToken();
if (value.text === "true") return new BooleanLiteral(true);
else if (value.text === "false") return new BooleanLiteral(false);
return null;
}
}

export function tokenToOp(tok: TokenData): Operator | null {
Expand Down
9 changes: 5 additions & 4 deletions src/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,12 @@ const module = new WebAssembly.Module(wasm);
let mem: WebAssembly.Memory;
const instance = new WebAssembly.Instance(module, {
env: {
print: (ptr: number) => {
printStr: (ptr: number) => {
const length = new Uint8Array(mem.buffer, ptr, 1)[0]
console.log("Length: ", length);
console.log("Mem: ", mem);
console.log("Print: " + String.fromCharCode(...[...(new Uint8Array(mem.buffer, ptr + 1, length))]))
console.log("String: " + String.fromCharCode(...[...(new Uint8Array(mem.buffer, ptr + 1, length))]));
},
printNum: (num: number) => {
console.log("Number: " + num);
}
}
});
Expand Down
Binary file modified test.wasm
Binary file not shown.
11 changes: 9 additions & 2 deletions test.wat
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
(module
(import "env" "print" (func $print
(import "env" "printStr" (func $printStr
(param i32)
)
)
(import "env" "printNum" (func $printNum
(param i32)
)
)
Expand All @@ -12,7 +16,10 @@
(export "main" (func $main))
(func $main
(block
(call $print
(call $printNum
(i32.const 5)
)
(call $printStr
(i32.const 0)
)
)
Expand Down

0 comments on commit 8ebbe1f

Please sign in to comment.