Skip to content

Commit

Permalink
[Draft] Import functions (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
AjaniBilby authored Mar 24, 2024
1 parent 68ea84c commit 1b62e92
Show file tree
Hide file tree
Showing 28 changed files with 569 additions and 268 deletions.
25 changes: 19 additions & 6 deletions source/bnf/syntax.bnf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
program ::= %w* ( stmt_top %w* )* ;
stmt_top ::= function | structure ;
stmt_top ::= function | structure | external ;


#=============================
Expand Down Expand Up @@ -32,8 +32,10 @@ constant ::= boolean
| string
| float | integer ;

string ::= string_text ;
string_text ::= %"\'" ( ( "\\" !"" ) | !( "\'" ) )* %"\'" ;
string ::= string_ascii | string_utf8 ;
string_ascii ::= %"\'" ( str_escape | !( "\'" ) )* %"\'" ;
string_utf8 ::= %"\"" ( str_escape | !( "\"" ) )* %"\"" ;
str_escape ::= %"\\" !"" ;

boolean ::= "true" | "false" ;

Expand Down Expand Up @@ -80,7 +82,7 @@ container ::= %(w* "[" w*) ( container_item ( %(w* "," w*) container_item )* %w*
#=============================
# Function
#=============================
function ::= func_head %w* ( block | ";" ) ;
function ::= func_head %w* ( block | ";" ) %w* ;
func_head ::= %("fn" w+) ...name %( w* "(" w* ) func_args %(w* ")" w*) %(":" w*) access ;
func_args ::= ( func_arg %w* ( %( "," w* ) func_arg )* )? ;
func_arg ::= ...name %( w* ":" w* ) access ;
Expand All @@ -91,10 +93,11 @@ block ::= %( "{" w* ) block_stmt* %( w* "}" w* ) ;
func_call ::= access func_call_body;
func_call_body ::= %( w* "(" w* ) ( expr %w* ( %( "," w* ) expr %w* )* )? %( ")" w* ) ;

return ::= %"return" "_call"? %w+ expr? %( ";" w* );
return ::= %"return" "_call"? ( %w+ expr)? %( w* ";" w* );
raise ::= %"raise" %w+ expr %( ";" w* ); # TODO rename to lift
# drop ::= %"drop" %w+ expr %( ";" w* );


#=============================
# Expression
#=============================
Expand All @@ -117,4 +120,14 @@ arg_list ::= ( expr %w* ","? %w* )* ;

if ::= %("if" w*) expr %w* expr %w* ( %"else" %w* expr )? ;

statement ::= expr %terminate ;
statement ::= expr %terminate ;


#=============================
# External
#=============================
external ::= %( "external" w+ ) ( ext_import | ext_export ) ;
ext_import ::= %( "import" w* "{" w* ) ext_imports* %( w* "}" w* "from" w*) string %(w* ";" w*) ;
ext_imports ::= function | ext_import_var ;
ext_import_var ::= %( "let" w* ) name %( w* ":" w* ) access %(w* ";" w*);
ext_export ::= "export" ;
144 changes: 132 additions & 12 deletions source/bnf/syntax.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export type Term_Stmt_top = {
count: number,
ref: _Shared.ReferenceRange,
value: [
(Term_Function | Term_Structure)
(Term_Function | Term_Structure | Term_External)
]
}
export declare function Parse_Stmt_top (i: string, refMapping?: boolean): _Shared.ParseError | {
Expand Down Expand Up @@ -235,7 +235,7 @@ export type Term_String = {
count: number,
ref: _Shared.ReferenceRange,
value: [
Term_String_text
(Term_String_ascii | Term_String_utf8)
]
}
export declare function Parse_String (i: string, refMapping?: boolean): _Shared.ParseError | {
Expand All @@ -245,28 +245,52 @@ export declare function Parse_String (i: string, refMapping?: boolean): _Shared.
isPartial: boolean
}

export type Term_String_text = {
type: 'string_text',
export type Term_String_ascii = {
type: 'string_ascii',
start: number,
end: number,
count: number,
ref: _Shared.ReferenceRange,
value: [
{ type: '(...)*', value: Array<({
type: '(...)',
{ type: '(...)*', value: Array<(Term_Str_escape | _Literal)>, start: number, end: number, count: number, ref: _Shared.ReferenceRange }
]
}
export declare function Parse_String_ascii (i: string, refMapping?: boolean): _Shared.ParseError | {
root: _Shared.SyntaxNode & Term_String_ascii,
reachBytes: number,
reach: null | _Shared.Reference,
isPartial: boolean
}

export type Term_String_utf8 = {
type: 'string_utf8',
start: number,
end: number,
count: number,
ref: _Shared.ReferenceRange,
value: [
_Literal & {value: "\x5c"},
_Literal
{ type: '(...)*', value: Array<(Term_Str_escape | _Literal)>, start: number, end: number, count: number, ref: _Shared.ReferenceRange }
]
} | _Literal)>, start: number, end: number, count: number, ref: _Shared.ReferenceRange }
}
export declare function Parse_String_utf8 (i: string, refMapping?: boolean): _Shared.ParseError | {
root: _Shared.SyntaxNode & Term_String_utf8,
reachBytes: number,
reach: null | _Shared.Reference,
isPartial: boolean
}

export type Term_Str_escape = {
type: 'str_escape',
start: number,
end: number,
count: number,
ref: _Shared.ReferenceRange,
value: [
_Literal
]
}
export declare function Parse_String_text (i: string, refMapping?: boolean): _Shared.ParseError | {
root: _Shared.SyntaxNode & Term_String_text,
export declare function Parse_Str_escape (i: string, refMapping?: boolean): _Shared.ParseError | {
root: _Shared.SyntaxNode & Term_Str_escape,
reachBytes: number,
reach: null | _Shared.Reference,
isPartial: boolean
Expand Down Expand Up @@ -914,7 +938,16 @@ export type Term_Return = {
ref: _Shared.ReferenceRange,
value: [
{ type: '(...)?', value: [] | [_Literal & {value: "\x5fcall"}], start: number, end: number, count: number, ref: _Shared.ReferenceRange },
{ type: '(...)?', value: [] | [Term_Expr], start: number, end: number, count: number, ref: _Shared.ReferenceRange }
{ type: '(...)?', value: [] | [{
type: '(...)',
start: number,
end: number,
count: number,
ref: _Shared.ReferenceRange,
value: [
Term_Expr
]
}], start: number, end: number, count: number, ref: _Shared.ReferenceRange }
]
}
export declare function Parse_Return (i: string, refMapping?: boolean): _Shared.ParseError | {
Expand Down Expand Up @@ -1212,3 +1245,90 @@ export declare function Parse_Statement (i: string, refMapping?: boolean): _Shar
reach: null | _Shared.Reference,
isPartial: boolean
}

export type Term_External = {
type: 'external',
start: number,
end: number,
count: number,
ref: _Shared.ReferenceRange,
value: [
(Term_Ext_import | Term_Ext_export)
]
}
export declare function Parse_External (i: string, refMapping?: boolean): _Shared.ParseError | {
root: _Shared.SyntaxNode & Term_External,
reachBytes: number,
reach: null | _Shared.Reference,
isPartial: boolean
}

export type Term_Ext_import = {
type: 'ext_import',
start: number,
end: number,
count: number,
ref: _Shared.ReferenceRange,
value: [
{ type: '(...)*', value: Array<Term_Ext_imports>, start: number, end: number, count: number, ref: _Shared.ReferenceRange },
Term_String
]
}
export declare function Parse_Ext_import (i: string, refMapping?: boolean): _Shared.ParseError | {
root: _Shared.SyntaxNode & Term_Ext_import,
reachBytes: number,
reach: null | _Shared.Reference,
isPartial: boolean
}

export type Term_Ext_imports = {
type: 'ext_imports',
start: number,
end: number,
count: number,
ref: _Shared.ReferenceRange,
value: [
(Term_Function | Term_Ext_import_var)
]
}
export declare function Parse_Ext_imports (i: string, refMapping?: boolean): _Shared.ParseError | {
root: _Shared.SyntaxNode & Term_Ext_imports,
reachBytes: number,
reach: null | _Shared.Reference,
isPartial: boolean
}

export type Term_Ext_import_var = {
type: 'ext_import_var',
start: number,
end: number,
count: number,
ref: _Shared.ReferenceRange,
value: [
Term_Name,
Term_Access
]
}
export declare function Parse_Ext_import_var (i: string, refMapping?: boolean): _Shared.ParseError | {
root: _Shared.SyntaxNode & Term_Ext_import_var,
reachBytes: number,
reach: null | _Shared.Reference,
isPartial: boolean
}

export type Term_Ext_export = {
type: 'ext_export',
start: number,
end: number,
count: number,
ref: _Shared.ReferenceRange,
value: [
_Literal & {value: "export"}
]
}
export declare function Parse_Ext_export (i: string, refMapping?: boolean): _Shared.ParseError | {
root: _Shared.SyntaxNode & Term_Ext_export,
reachBytes: number,
reach: null | _Shared.Reference,
isPartial: boolean
}
27 changes: 24 additions & 3 deletions source/bnf/syntax.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion source/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Function from "~/compiler/function.ts";
import Package from "~/compiler/package.ts";
import Project from "~/compiler/project.ts";
import { DisplayTimers, TimerStart, TimerEnd } from "~/helper.ts";
import { Panic } from "~/helper.ts";
import { Panic } from "~/compiler/helper.ts";

if (Deno.args.includes("--version")) {
console.log("version: 0.0.0");
Expand Down
3 changes: 2 additions & 1 deletion source/compiler/codegen/allocation/stack.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AssertUnreachable, AlignUpInteger, AlignDownInteger, LatentValue } from "~/helper.ts";
import { AlignUpInteger, AlignDownInteger } from "~/compiler/helper.ts";
import { AssertUnreachable, LatentValue } from "~/helper.ts";

/**
* Used for calculating the relative stack location of variables within a function stack
Expand Down
10 changes: 6 additions & 4 deletions source/compiler/codegen/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import { BasePointerType, LinearType, OperandType, SolidType, IsRuntimeType, IsS
import { IntrinsicType, IntrinsicValue, none, never } from "~/compiler/intrinsic.ts";
import { Instruction, AnyInstruction } from "~/wasm/index.ts";
import { ResolveLinearType, Store } from "~/compiler/codegen/expression/helper.ts"
import { AssertUnreachable, Panic } from "~/helper.ts";
import { AssertUnreachable } from "~/helper.ts";
import { ReferenceRange } from "~/parser.ts";
import { CompileExpr } from "~/compiler/codegen/expression/index.ts";
import { VirtualType } from "~/compiler/intrinsic.ts";
import { Variable } from "~/compiler/codegen/variable.ts";
import { Block } from "~/wasm/instruction/control-flow.ts";
import { Panic } from "~/compiler/helper.ts";

export class Context {
file: File;
Expand Down Expand Up @@ -281,7 +283,7 @@ function CompileStatement(ctx: Context, syntax: Syntax.Term_Statement) {


function CompileReturn(ctx: Context, syntax: Syntax.Term_Return): typeof never {
const maybe_expr = syntax.value[1].value[0];
const maybe_expr = syntax.value[1].value[0]?.value[0];
const isTail = syntax.value[0].value.length > 0;
const ref = syntax.ref;

Expand All @@ -291,7 +293,7 @@ function CompileReturn(ctx: Context, syntax: Syntax.Term_Return): typeof never {
);

// Guard: return none
if (ctx.function.returns.length === 0) {
if (ctx.function.returns instanceof VirtualType) {
if (maybe_expr) Panic(
`${colors.red("Error")}: This function should have no return value\n`,
{ path: ctx.file.path, name: ctx.file.name, ref }
Expand All @@ -300,7 +302,7 @@ function CompileReturn(ctx: Context, syntax: Syntax.Term_Return): typeof never {
ctx.scope.cleanup(true);
ctx.block.push(Instruction.return());
ctx.done = true;
return never;
return ctx.function.returns;
}

if (!maybe_expr) Panic(
Expand Down
28 changes: 27 additions & 1 deletion source/compiler/codegen/expression/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import * as colors from "https://deno.land/[email protected]/fmt/colors.ts";

import type * as Syntax from "~/bnf/syntax.d.ts";
import { IntrinsicType, bool, u8, i8, u16, i16, u32, i32, u64, i64, f32, f64 } from "~/compiler/intrinsic.ts";
import { AssertUnreachable, Panic } from "~/helper.ts";
import { AssertUnreachable } from "~/helper.ts";
import { IntrinsicValue } from "~/compiler/intrinsic.ts";
import { Instruction } from "~/wasm/index.ts";
import { SolidType } from "~/compiler/codegen/expression/type.ts";
import { Context } from "~/compiler/codegen/context.ts";
import { Panic } from "~/compiler/helper.ts";

export function CompileConstant(ctx: Context, syntax: Syntax.Term_Constant, expect?: SolidType): IntrinsicValue {
if (!(expect instanceof IntrinsicType)) expect = undefined;
Expand Down Expand Up @@ -146,4 +147,29 @@ function CompileFloat(ctx: Context, syntax: Syntax.Term_Float, expect?: Intrinsi
ctx.block.push(Instruction.const.f32(num));

return f32.value;
}

export function SimplifyString(syntax: Syntax.Term_String) {
const inner = syntax.value[0];
const type = inner.type === "string_ascii" ? "ascii" : "utf8";
let str = "";

for (const chunk of inner.value[0].value) {
if (chunk.type == "literal") {
str += chunk.value;
continue;
}

const esc = chunk.value[0].value;
switch (esc) {
case "0": str += "\0"; break;
case "f": str += "\f"; break;
case "n": str += "\n"; break;
case "r": str += "\r"; break;
case "v": str += "\v"; break;
default: str += esc;
}
}

return { type, str }
}
2 changes: 1 addition & 1 deletion source/compiler/codegen/expression/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Instruction } from "~/wasm/index.ts";
import { SourceView } from "~/parser.ts";
import { Context } from "~/compiler/codegen/context.ts";
import { Assign } from "~/compiler/codegen/context.ts";
import { Panic } from "~/helper.ts";
import { Panic } from "~/compiler/helper.ts";

export function StructBuilder(ctx: Context, syntax: Syntax.Term_Container, expect?: SolidType): OperandType {
if (!(expect instanceof Structure)) Panic(
Expand Down
3 changes: 2 additions & 1 deletion source/compiler/codegen/expression/helper.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type * as Syntax from "~/bnf/syntax.d.ts";

import { AssertUnreachable, LatentOffset, Panic } from "~/helper.ts";
import { AssertUnreachable, LatentOffset } from "~/helper.ts";
import { BasePointerType, LinearType } from "~/compiler/codegen/expression/type.ts";
import { ReferenceRange } from "~/bnf/shared.js";
import { IntrinsicType } from "~/compiler/intrinsic.ts";
import { Instruction } from "~/wasm/index.ts";
import { SourceView } from "~/parser.ts";
import { Context } from "~/compiler/codegen/context.ts";
import { Panic } from "~/compiler/helper.ts";


export function MaybeSingularExprArg(syntax: Syntax.Term_Expr) {
Expand Down
2 changes: 1 addition & 1 deletion source/compiler/codegen/expression/infix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { ReferenceRange } from "~/parser.ts";
import { Instruction } from "~/wasm/index.ts";
import { CompileArg } from "~/compiler/codegen/expression/operand.ts";
import { Context } from "~/compiler/codegen/context.ts";
import { Panic } from "~/helper.ts";
import { Panic } from "~/compiler/helper.ts";


export function CompileInfix(ctx: Context, lhs: PrecedenceTree, op: string, rhs: PrecedenceTree, ref: ReferenceRange, expect?: SolidType): OperandType {
Expand Down
Loading

0 comments on commit 1b62e92

Please sign in to comment.