Skip to content

Commit

Permalink
add type casting in destructured declarations
Browse files Browse the repository at this point in the history
  • Loading branch information
michele-nuzzi committed Feb 26, 2025
1 parent 618e8d4 commit fea2874
Show file tree
Hide file tree
Showing 18 changed files with 313 additions and 44 deletions.
2 changes: 1 addition & 1 deletion src/ast/nodes/statements/PebbleStmt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export type PebbleStmt
| ForStmt
| ForOfStmt
| WhileStmt
| DoWhileStmt
// | DoWhileStmt
| ReturnStmt
| BlockStmt
| BreakStmt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class ArrayLikeDeconstr
constructor(
readonly elements: VarDecl[],
readonly rest: Identifier | undefined,
readonly type: AstTypeExpr | undefined, // just for the type checker, or func params, usually this is inferred
public type: AstTypeExpr | undefined, // just for the type checker, or func params, usually this is inferred
readonly initExpr: PebbleExpr | undefined,
public flags: number,
readonly range: SourceRange,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class NamedDeconstructVarDecl
readonly name: Identifier,
readonly fields: Map<string, VarDecl>,
readonly rest: Identifier | undefined,
readonly type: AstTypeExpr | undefined, // can be undefined when use ad function parameter
public type: AstTypeExpr | undefined, // can be undefined when use ad function parameter
readonly initExpr: PebbleExpr | undefined, // can be undefined when use ad function parameter
public flags: CommonFlags,
readonly range: SourceRange,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class SimpleVarDecl
{
constructor(
readonly name: Identifier,
readonly type: AstTypeExpr | undefined,
public type: AstTypeExpr | undefined,
readonly initExpr: PebbleExpr | undefined,
public flags: CommonFlags,
readonly range: SourceRange,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class SingleDeconstructVarDecl
constructor(
readonly fields: Map<string, VarDecl>,
readonly rest: Identifier | undefined,
readonly type: AstTypeExpr | undefined,
public type: AstTypeExpr | undefined,
readonly initExpr: PebbleExpr | undefined,
public flags: CommonFlags,
readonly range: SourceRange
Expand Down
14 changes: 12 additions & 2 deletions src/compiler/AstCompiler/AstCompiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,22 @@ export class AstCompiler extends DiagnosticEmitter
throw new Error("_compileParsedSource: source has no statements");
}

this.program

this.program.files.set(
src.internalPath,
this._compileSourceStatements( src.statements )

Check failure on line 110 in src/compiler/AstCompiler/AstCompiler.ts

View workflow job for this annotation

GitHub Actions / CI (ubuntu-latest)

Argument of type 'void' is not assignable to parameter of type 'TirSource'.

Check failure on line 110 in src/compiler/AstCompiler/AstCompiler.ts

View workflow job for this annotation

GitHub Actions / CI (macos-latest)

Argument of type 'void' is not assignable to parameter of type 'TirSource'.
);

return this.diagnostics;
}

/**
* assumes the types have been collected before
*/
private _compileSourceStatements( stmts: PebbleStmt[] )
{
const result = [];
}

/**
* Collect all types declared in the top-level statements
*
Expand Down
6 changes: 6 additions & 0 deletions src/compiler/tir/expressions/TirExpr.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@


export type TirExpr
=
| TirBinaryExpr

Check failure on line 5 in src/compiler/tir/expressions/TirExpr.ts

View workflow job for this annotation

GitHub Actions / CI (ubuntu-latest)

Cannot find name 'TirBinaryExpr'.

Check failure on line 5 in src/compiler/tir/expressions/TirExpr.ts

View workflow job for this annotation

GitHub Actions / CI (ubuntu-latest)

Exported type alias 'TirExpr' has or is using private name 'TirBinaryExpr'.

Check failure on line 5 in src/compiler/tir/expressions/TirExpr.ts

View workflow job for this annotation

GitHub Actions / CI (macos-latest)

Cannot find name 'TirBinaryExpr'.

Check failure on line 5 in src/compiler/tir/expressions/TirExpr.ts

View workflow job for this annotation

GitHub Actions / CI (macos-latest)

Exported type alias 'TirExpr' has or is using private name 'TirBinaryExpr'.
;
34 changes: 34 additions & 0 deletions src/compiler/tir/statements/TirForOfStmt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { HasSourceRange } from "../../../ast/nodes/HasSourceRange";
import { SourceRange } from "../../../ast/Source/SourceRange";
import { TirExpr } from "../expressions/TirExpr";
import { TirStmt, TirVarDecl } from "./TirStmt";

/**
* for( `elemDeclaration` of iterable ) body
*/
export class TirForOfStmt
implements HasSourceRange
{
constructor(
readonly elemDeclaration: TirForOfElemDecl,
readonly iterable: TirExpr,
readonly body: TirStmt,
readonly range: SourceRange,
) {}
}

/**
* just like function parameters
* destructured elements are moved in the `for...of` body
*
* unlike funciton parameters
* `for...of` element type is inferred from the iterable
*/
export class TirForOfElemDecl
implements HasSourceRange
{
constructor(
readonly name: string,
readonly range: SourceRange,
) {}
}
21 changes: 21 additions & 0 deletions src/compiler/tir/statements/TirForStmt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { HasSourceRange } from "../../../ast/nodes/HasSourceRange";
import { SourceRange } from "../../../ast/Source/SourceRange";
import { TirExpr } from "../expressions/TirExpr";
import { TirStmt, TirVarDecl } from "./TirStmt";

/**
* ***NOT*** for...of loop
*
* for( init; condition; update ) body
*/
export class TirForStmt
implements HasSourceRange
{
constructor(
readonly init: TirVarDecl[],
readonly condition: TirExpr | undefined,
readonly update: TirExpr | undefined,
readonly body: TirStmt,
readonly range: SourceRange,
) {}
}
28 changes: 28 additions & 0 deletions src/compiler/tir/statements/TirFuncDecl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { HasSourceRange } from "../../../ast/nodes/HasSourceRange";
import { SourceRange } from "../../../ast/Source/SourceRange";
import { TirExpr } from "../expressions/TirExpr";
import { TirConcreteType } from "../types/TirConcreteType";


export class TirFuncDecl
implements HasSourceRange
{
constructor(
readonly name: string,
readonly params: TirSimpleFuncParam[],
readonly returnType: TirConcreteType,
readonly body: TirBlockStmt,

Check failure on line 14 in src/compiler/tir/statements/TirFuncDecl.ts

View workflow job for this annotation

GitHub Actions / CI (ubuntu-latest)

Cannot find name 'TirBlockStmt'.

Check failure on line 14 in src/compiler/tir/statements/TirFuncDecl.ts

View workflow job for this annotation

GitHub Actions / CI (ubuntu-latest)

Parameter 'body' of constructor from exported class has or is using private name 'TirBlockStmt'.

Check failure on line 14 in src/compiler/tir/statements/TirFuncDecl.ts

View workflow job for this annotation

GitHub Actions / CI (macos-latest)

Cannot find name 'TirBlockStmt'.

Check failure on line 14 in src/compiler/tir/statements/TirFuncDecl.ts

View workflow job for this annotation

GitHub Actions / CI (macos-latest)

Parameter 'body' of constructor from exported class has or is using private name 'TirBlockStmt'.
readonly range: SourceRange,
) {}
}

export class TirSimpleFuncParam
implements HasSourceRange
{
constructor(
readonly name: string,
readonly type: TirConcreteType, // params MUST have a type, even with initExpr
readonly initExpr: TirExpr | undefined, // optional initializer for params
readonly range: SourceRange,
) {}
}
15 changes: 15 additions & 0 deletions src/compiler/tir/statements/TirIfStmt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { HasSourceRange } from "../../../ast/nodes/HasSourceRange";
import { SourceRange } from "../../../ast/Source/SourceRange";
import { TirExpr } from "../expressions/TirExpr";
import { TirStmt } from "./TirStmt";

export class TirIfStmt
implements HasSourceRange
{
constructor(
readonly condition: TirExpr,
readonly thenBranch: TirStmt,
readonly elseBranch: TirStmt | undefined,
readonly range: SourceRange,
) {}
}
45 changes: 44 additions & 1 deletion src/compiler/tir/statements/TirStmt.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,49 @@
import { TirForOfStmt } from "./TirForOfStmt";
import { TirForStmt } from "./TirForStmt";
import { TirFuncDecl, TirSimpleFuncParam } from "./TirFuncDecl";
import { TirIfStmt } from "./TirIfStmt";
import { TirSimpleVarDecl } from "./TirVarDecl/TirSimpleVarDecl";

export type TirStmt
=
= TirIfStmt
| TirVarDecl
| TirFuncDecl
// destructured params are immediately replaced at translation
// TIR only has simple parameters
// AST destructured params just become
//
// function astFunc({ a, b }: Thing) { ... }
//
// function tirFunc( §thing#1a3f: Thing ) {
// const { a, b } = §thing#1a3f;
// }
| TirSimpleFuncParam
| TirForStmt
// easier to optimize than normal for loop
// we remember the difference between the two
| TirForOfStmt
| TirWhileStmt

Check failure on line 25 in src/compiler/tir/statements/TirStmt.ts

View workflow job for this annotation

GitHub Actions / CI (ubuntu-latest)

Cannot find name 'TirWhileStmt'.

Check failure on line 25 in src/compiler/tir/statements/TirStmt.ts

View workflow job for this annotation

GitHub Actions / CI (ubuntu-latest)

Exported type alias 'TirStmt' has or is using private name 'TirWhileStmt'.

Check failure on line 25 in src/compiler/tir/statements/TirStmt.ts

View workflow job for this annotation

GitHub Actions / CI (macos-latest)

Cannot find name 'TirWhileStmt'.

Check failure on line 25 in src/compiler/tir/statements/TirStmt.ts

View workflow job for this annotation

GitHub Actions / CI (macos-latest)

Exported type alias 'TirStmt' has or is using private name 'TirWhileStmt'.
| TirReturnStmt

Check failure on line 26 in src/compiler/tir/statements/TirStmt.ts

View workflow job for this annotation

GitHub Actions / CI (ubuntu-latest)

Cannot find name 'TirReturnStmt'.

Check failure on line 26 in src/compiler/tir/statements/TirStmt.ts

View workflow job for this annotation

GitHub Actions / CI (ubuntu-latest)

Exported type alias 'TirStmt' has or is using private name 'TirReturnStmt'.

Check failure on line 26 in src/compiler/tir/statements/TirStmt.ts

View workflow job for this annotation

GitHub Actions / CI (macos-latest)

Cannot find name 'TirReturnStmt'.

Check failure on line 26 in src/compiler/tir/statements/TirStmt.ts

View workflow job for this annotation

GitHub Actions / CI (macos-latest)

Exported type alias 'TirStmt' has or is using private name 'TirReturnStmt'.
| TirBlockStmt

Check failure on line 27 in src/compiler/tir/statements/TirStmt.ts

View workflow job for this annotation

GitHub Actions / CI (ubuntu-latest)

Cannot find name 'TirBlockStmt'.

Check failure on line 27 in src/compiler/tir/statements/TirStmt.ts

View workflow job for this annotation

GitHub Actions / CI (macos-latest)

Cannot find name 'TirBlockStmt'.
| TirBreakStmt
| TirContinueStmt
| TirFailStmt
| TirAssertStmt
| TirTestStmt
| TirMatchStmt
| TirExportStarStmt
| TirImportStarStmt
| TirExportStmt
| TirImportStmt
| TirTypeImplementsStmt
| TirAssignmentStmt
;

export type TirVarDecl
= TirSimpleVarDecl
| TirNamedDeconstructVarDecl
| TirSingleDeconstructVarDecl
| TirArrayLikeDeconstr
;

export function isTirStmt( thing: any ): thing is TirStmt
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { HasSourceRange } from "../../../../ast/nodes/HasSourceRange";
import { SourceRange } from "../../../../ast/Source/SourceRange";
import { TirExpr } from "../../expressions/TirExpr";
import { TirConcreteType } from "../../types/TirConcreteType";

export class TirNamedDeconstructVarDecl
implements HasSourceRange
{
constructor(
readonly name: string,
readonly type: TirConcreteType,
readonly initExpr: TirExpr,
readonly range: SourceRange,
) {}
}
15 changes: 15 additions & 0 deletions src/compiler/tir/statements/TirVarDecl/TirSimpleVarDecl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { HasSourceRange } from "../../../../ast/nodes/HasSourceRange";
import { SourceRange } from "../../../../ast/Source/SourceRange";
import { TirExpr } from "../../expressions/TirExpr";
import { TirConcreteType } from "../../types/TirConcreteType";

export class TirSimpleVarDecl
implements HasSourceRange
{
constructor(
readonly name: string,
readonly type: TirConcreteType,
readonly initExpr: TirExpr,
readonly range: SourceRange,
) {}
}
53 changes: 47 additions & 6 deletions src/parser/Parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1277,7 +1277,7 @@ export class Parser extends DiagnosticEmitter
continue; // checks for close brace and exits while loop
}

if( !fieldName ) { // (eg: { , ... }) ??
if( !fieldName ) { // (eg: { , ... }) ??
this.error(
DiagnosticCode.Identifier_expected,
tn.range()
Expand All @@ -1289,7 +1289,18 @@ export class Parser extends DiagnosticEmitter
{
element = SimpleVarDecl.onlyIdentifier( fieldName, flags );
elements.set( fieldName.text, element );
tn.skip( Token.Comma ); // skip comma if present

if(tn.skip(Token.CloseBrace)) break; // last field destructured

if( !tn.skip(Token.Comma) )
{
this.error(
DiagnosticCode._0_expected,
tn.range(), ","
);
return undefined;
}

continue; // early continue to check for close brace or next field
}
// else ther is colon (eg: { field: ... })
Expand Down Expand Up @@ -1321,6 +1332,20 @@ export class Parser extends DiagnosticEmitter
return undefined;
}

if( tn.skip( Token.As ) )
{
const castType = this.parseTypeExpr();
if( !castType )
{
this.error(
DiagnosticCode.Type_expected,
tn.range()
);
return undefined;
}
element.type = castType;
}

elements.set( fieldName.text, element );
tn.skip( Token.Comma ); // skip comma if present
} // while( !tn.skip( Token.CloseBrace ) )
Expand Down Expand Up @@ -1385,6 +1410,20 @@ export class Parser extends DiagnosticEmitter
elem.initExpr ? elem.initExpr.range : elem.type!.range
);

if( tn.skip(Token.As) )
{
const castType = this.parseTypeExpr();
if( !castType )
{
this.error(
DiagnosticCode.Type_expected,
tn.range()
);
return undefined;
}
elem.type = castType;
}

elems.push( elem );

if( tn.skip( Token.Comma ) ) continue;
Expand Down Expand Up @@ -2604,10 +2643,10 @@ export class Parser extends DiagnosticEmitter
statement = this.parseContinue();
break;
}
case Token.Do: {
statement = this.parseDoStatement();
break;
}
// case Token.Do: {
// statement = this.parseDoStatement();
// break;
// }
case Token.For: {
statement = this.parseForStatement();
break;
Expand Down Expand Up @@ -2865,6 +2904,7 @@ export class Parser extends DiagnosticEmitter
return ret;
}

/*
parseDoStatement(): DoWhileStmt | undefined
{
const tn = this.tn;
Expand Down Expand Up @@ -2911,6 +2951,7 @@ export class Parser extends DiagnosticEmitter
tn.skip(Token.Semicolon);
return result;
}
*/

parseForStatement(): ForStmt | ForOfStmt | undefined
{
Expand Down
Loading

0 comments on commit fea2874

Please sign in to comment.