UNPKG

jaycc

Version:

### the Javascript C Compiler

244 lines (201 loc) 5.04 kB
/* ast.ts */ enum Etype { Int }; type Numberconstant = number & {tag:string}; type Expr = Numberconstant; type Decl = any; type Assignment = any; type Identifier = string & {tag:string}; type Datatype = Etype & {tag:string}; type AST = | Program | Numberconstant | Decl | Assignment | Identifier | Datatype | ASTfunction | Codeblock | Stm | Returnstm; type Tstm = ( | (Decl & {tag:string}) | (Assignment & {tag:string}) | Returnstm ); /*abstract*/ interface Iase { constructor: Function; tag: string; } interface Ireturnstm extends Iase { expr: Expr; } interface Istm { decl?: Decl; assignment?: Assignment; returnstm?: Returnstm; } interface IsyntaxE extends Error { constructor: Function; } interface Icodeblock extends Iase { stms: Stm[]; } interface Ifunction extends Iase { type: Datatype; name: Identifier; /* params: Variable[]; */ body: Codeblock; } interface Iprogram extends Iase { fns:ASTfunction[]; } let test:()=>void; let log:(...data:any[])=>void; let numberconstant:(input:number)=>Numberconstant; let expr:(input:Numberconstant)=>Expr; let identifier:(input:string)=>Identifier; let datatype:(input:Etype)=>Datatype; log = console.log; numberconstant = (input:number): Numberconstant => { let ret:Numberconstant; ret = new Number(input) as Numberconstant; ret.tag = 'Numberconstant'; return ret; } expr = (input:Numberconstant): Expr => { let ret: Expr; ret = new Number(input as number) as Expr; ret.tag = 'Expr'; return ret; } identifier = (input:string): Identifier => { let ret: Identifier; ret = new String(input) as Identifier; ret.tag = 'Identifier'; return ret; } datatype = (input:Etype): Datatype => { let ret: Datatype; ret = new Number(input as number) as Datatype; ret.tag = 'Datatype'; return ret; } class SyntaxException extends Error implements IsyntaxE { constructor(msg:string) { super(msg); } } abstract class ASE implements Iase { abstract tag: string; constructor() { void 0; } } class ASTfunction extends ASE implements Ifunction { tag: string; type: Datatype; name: Identifier; body: Codeblock; constructor(type:Datatype,name:Identifier,body:Codeblock) { super(); this.tag = 'Function'; this.type = type; this.name = name; this.body = body; } } class Codeblock extends ASE implements Icodeblock { tag: string; stms: Stm[]; constructor(input:Stm[]) { super(); this.tag = 'Codeblock'; this.stms = input; } } class Returnstm extends ASE implements Ireturnstm { tag: string; expr: Expr; constructor(input:Expr) { super(); this.tag = 'Returnstm'; this.expr = input; } } class Stm implements Istm { tag: string; decl?: Decl; assignment?: Assignment; returnstm?: Returnstm; constructor(input:Decl); constructor(input:Assignment); constructor(input:Returnstm); constructor(input:Tstm) { let ok:boolean; this.tag = 'Stm'; ok = false; switch(input.tag) { case 'Decl': this.decl = input; ok = true; break; case 'Assigment': this.assignment = input; ok = true; break; case 'Returnstm': this.returnstm = input; ok = true; break; default: ok = false; break; } if (!ok) throw new SyntaxException('Syntax error in statement'); } } class Program extends ASE implements Iprogram { tag: string; fns:ASTfunction[]; constructor(input:ASTfunction[]) { super(); this.tag = 'Program'; this.fns = input; } } test = (): void => { let r:Returnstm; let e:Expr; let s:Stm; let n:Numberconstant; let c:Codeblock; let i:Identifier; let d:Datatype; let f:ASTfunction; let p:Program; let ast:AST; n = numberconstant(5); e = expr(n); r = new Returnstm(e); s = new Stm(r); c = new Codeblock([s]); i = identifier('main'); d = datatype(Etype.Int); f = new ASTfunction(d, i, c); p = new Program([f]); ast = p; log(JSON.stringify(ast,null,3)); return void 0; } export { test }; export type { AST }; export type { Numberconstant, Expr, Decl, Assignment, Identifier, Datatype }; export { numberconstant, expr, identifier, datatype }; export { ASTfunction, Codeblock, Returnstm, Stm, Program, SyntaxException, Etype };