-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
reworked branch management for new merging
- Loading branch information
1 parent
8689ae5
commit 79d3557
Showing
3 changed files
with
135 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import * as colors from "https://deno.land/[email protected]/fmt/colors.ts"; | ||
|
||
import type * as Syntax from "~/bnf/syntax.d.ts"; | ||
import { LinearType, SolidType, OperandType } from "~/compiler/codegen/expression/type.ts"; | ||
import { IntrinsicValue, VirtualType, bool } from "~/compiler/intrinsic.ts"; | ||
import { GetSolidType } from "~/compiler/codegen/expression/type.ts"; | ||
import { CompileExpr } from "~/compiler/codegen/expression/index.ts"; | ||
import { IsNamespace } from "~/compiler/file.ts"; | ||
import { Instruction } from "~/wasm/index.ts"; | ||
import { Context } from "~/compiler/codegen/context.ts"; | ||
import { Panic } from "~/compiler/helper.ts"; | ||
|
||
|
||
export function CompileIf(ctx: Context, syntax: Syntax.Term_If, expect?: SolidType): OperandType { | ||
const cond = CompileExpr(ctx, syntax.value[0]); | ||
if (cond instanceof LinearType && cond.type !== bool.value) Panic( | ||
`${colors.red("Error")}: Invalid comparison type ${cond.type.getTypeName()}\n`, | ||
{ path: ctx.file.path, name: ctx.file.name, ref: syntax.value[0].ref } | ||
); | ||
|
||
const lifter = ctx.scope.stack.allocate(0, 0); | ||
|
||
const brIf = CompileBranchBody(ctx, syntax.value[1], expect); | ||
|
||
let typeIdx = 0x40; | ||
if (brIf.type instanceof IntrinsicValue) typeIdx = ctx.file.getModule().makeType([], [brIf.type.type.bitcode]); | ||
else if (brIf.type instanceof VirtualType) typeIdx = 0x40; | ||
else if (brIf.type instanceof LinearType) { | ||
lifter.align = brIf.type.getAlignment(); | ||
lifter.size = brIf.type.getSize(); | ||
|
||
if (!brIf.type.alloc) Panic( | ||
`${colors.red("Error")}: Lifted struct somehow has no allocation\n`, | ||
{ path: ctx.file.path, name: ctx.file.name, ref: syntax.value[1].ref } | ||
); | ||
|
||
brIf.type.alloc.moveTo(lifter); | ||
} | ||
|
||
const elseSyntax = syntax.value[2].value[0]; | ||
if (elseSyntax) { | ||
const brElse = CompileBranchBody(ctx, elseSyntax.value[0], GetSolidType(brIf.type)); | ||
|
||
if (brIf.type instanceof LinearType) { | ||
if ( !(brElse.type instanceof LinearType) || brIf.type.type !== brElse.type.type ) Panic( | ||
`${colors.red("Error")}: Type miss-match between if statement results, ${brIf.type.getTypeName()} != ${brElse.type.getTypeName()}\n`, | ||
{ path: ctx.file.path, name: ctx.file.name, ref: syntax.ref } | ||
); | ||
|
||
if (!brElse.type.alloc) Panic( | ||
`${colors.red("Error")}: Lifted struct somehow has no allocation\n`, | ||
{ path: ctx.file.path, name: ctx.file.name, ref: elseSyntax.value[0].ref } | ||
); | ||
|
||
brElse.type.alloc.moveTo(lifter); | ||
} else if (brIf.type != brElse.type) Panic( | ||
`${colors.red("Error")}: Type miss-match between if statement results, ${brIf.type.getTypeName()} != ${brElse.type.getTypeName()}\n`, | ||
{ path: ctx.file.path, name: ctx.file.name, ref: syntax.ref } | ||
); | ||
|
||
|
||
ctx.block.push(Instruction.if(typeIdx, brIf.scope.block, brElse.scope?.block)); | ||
|
||
ctx.exited ||= brIf.scope.exited && brElse.scope.exited; | ||
ctx.block.push(Instruction.unreachable()); | ||
} else { | ||
ctx.block.push(Instruction.if(typeIdx, brIf.scope.block)); | ||
} | ||
|
||
return brIf.type; | ||
} | ||
|
||
|
||
function CompileBranchBody(ctx: Context, syntax: Syntax.Term_Expr, expect?: SolidType) { | ||
const stack = ctx.scope.stack.checkpoint(); | ||
const scope = ctx.child(); | ||
|
||
// If there is a single block, inline it | ||
// Otherwise compile the expression inline | ||
const type = InlineBlock(scope, syntax) | ||
|| CompileExpr(scope, syntax, expect); | ||
|
||
if (IsNamespace(type)) Panic( | ||
`${colors.red("Error")}: Unsupported namespace yielded from a branch\n`, | ||
{ path: ctx.file.path, name: ctx.file.name, ref: syntax.ref } | ||
); | ||
|
||
scope.mergeBlock(); | ||
stack.restore(); | ||
|
||
return { stack, scope, type }; | ||
} | ||
|
||
function InlineBlock(ctx: Context, syntax: Syntax.Term_Expr) { | ||
// Expression only has a single arg | ||
if (syntax.value[1].value.length !== 0) return null; | ||
|
||
const arg = syntax.value[0]; | ||
|
||
// No prefix operations | ||
if (arg.value[0].value.length !== 0) return null; | ||
|
||
// No postfix operations | ||
if (arg.value[2].value.length !== 0) return null; | ||
|
||
// Only a block argument | ||
if (arg.value[1].value[0].type != "block") return null; | ||
|
||
// Compile each of the block_stmt in the current context | ||
const block = arg.value[1].value[0]; | ||
ctx.compile(block.value[0].value); | ||
|
||
return ctx.raiseType; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,18 +2,19 @@ import * as colors from "https://deno.land/[email protected]/fmt/colors.ts"; | |
|
||
import type * as Syntax from "~/bnf/syntax.d.ts"; | ||
import Structure from "~/compiler/structure.ts"; | ||
import { LinearType, SolidType, OperandType } from "~/compiler/codegen/expression/type.ts"; | ||
import { IntrinsicValue, VirtualType, bool, never } from "~/compiler/intrinsic.ts"; | ||
import { ArrayBuilder, StructBuilder } from "~/compiler/codegen/expression/container.ts"; | ||
import { SolidType, OperandType } from "~/compiler/codegen/expression/type.ts"; | ||
import { AssertUnreachable } from "~/helper.ts"; | ||
import { CompilePostfixes } from "~/compiler/codegen/expression/postfix/index.ts"; | ||
import { CompileConstant } from "~/compiler/codegen/expression/constant.ts"; | ||
import { CompilePrefix } from "~/compiler/codegen/expression/prefix.ts"; | ||
import { CompileExpr } from "~/compiler/codegen/expression/index.ts"; | ||
import { IsNamespace } from "~/compiler/file.ts"; | ||
import { Instruction } from "~/wasm/index.ts"; | ||
import { CompileIf } from "~/compiler/codegen/expression/flow-control.ts"; | ||
import { Context } from "~/compiler/codegen/context.ts"; | ||
import { Panic } from "~/compiler/helper.ts"; | ||
import { never } from "~/compiler/intrinsic.ts"; | ||
|
||
|
||
|
||
export function CompileArg(ctx: Context, syntax: Syntax.Term_Expr_arg, expect?: SolidType, tailCall = false): OperandType { | ||
|
@@ -80,81 +81,6 @@ function CompileName(ctx: Context, syntax: Syntax.Term_Name): OperandType { | |
return variable.type; | ||
} | ||
|
||
function CompileIf(ctx: Context, syntax: Syntax.Term_If, expect?: SolidType): OperandType { | ||
const cond = CompileExpr(ctx, syntax.value[0]); | ||
if (cond instanceof LinearType && cond.type !== bool.value) Panic( | ||
`${colors.red("Error")}: Invalid comparison type ${cond.type.getTypeName()}\n`, | ||
{ path: ctx.file.path, name: ctx.file.name, ref: syntax.value[0].ref } | ||
); | ||
|
||
const lifter = ctx.scope.stack.allocate(0, 0); | ||
|
||
const stackIf = ctx.scope.stack.checkpoint(); | ||
const scopeIf = ctx.child(); | ||
const typeIf = CompileExpr(scopeIf, syntax.value[1], expect); | ||
if (IsNamespace(typeIf)) Panic( | ||
`${colors.red("Error")}: Unsupported namespace yielded from if block\n`, | ||
{ path: ctx.file.path, name: ctx.file.name, ref: syntax.ref } | ||
); | ||
scopeIf.mergeBlock(); | ||
stackIf.restore(); | ||
|
||
let typeIdx = 0x40; | ||
if (typeIf instanceof IntrinsicValue) typeIdx = ctx.file.getModule().makeType([], [typeIf.type.bitcode]); | ||
else if (typeIf instanceof VirtualType) typeIdx = 0x40; | ||
else if (typeIf instanceof LinearType) { | ||
lifter.align = typeIf.getAlignment(); | ||
lifter.size = typeIf.getSize(); | ||
|
||
if (!typeIf.alloc) Panic( | ||
`${colors.red("Error")}: Lifted struct somehow has no allocation\n`, | ||
{ path: ctx.file.path, name: ctx.file.name, ref: syntax.value[1].ref } | ||
); | ||
|
||
typeIf.alloc.moveTo(lifter); | ||
} | ||
|
||
if (syntax.value[2].value[0]) { | ||
const stackElse = ctx.scope.stack.checkpoint(); | ||
const scopeElse = ctx.child(); | ||
const typeElse = CompileExpr(scopeElse, syntax.value[2].value[0].value[0], expect); | ||
|
||
if (IsNamespace(typeElse)) Panic( | ||
`${colors.red("Error")}: Unsupported namespace yielded from else block\n`, | ||
{ path: ctx.file.path, name: ctx.file.name, ref: syntax.ref } | ||
); | ||
scopeElse.mergeBlock(); | ||
stackElse.restore(); | ||
|
||
if (typeIf instanceof LinearType) { | ||
if ( !(typeElse instanceof LinearType) || typeIf.type !== typeElse.type ) Panic( | ||
`${colors.red("Error")}: Type miss-match between if statement results, ${typeIf.getTypeName()} != ${typeElse.getTypeName()}\n`, | ||
{ path: ctx.file.path, name: ctx.file.name, ref: syntax.ref } | ||
); | ||
|
||
if (!typeElse.alloc) Panic( | ||
`${colors.red("Error")}: Lifted struct somehow has no allocation\n`, | ||
{ path: ctx.file.path, name: ctx.file.name, ref: syntax.value[2].value[0].value[0].ref } | ||
); | ||
|
||
typeElse.alloc.moveTo(lifter); | ||
} else if (typeIf != typeElse) Panic( | ||
`${colors.red("Error")}: Type miss-match between if statement results, ${typeIf.getTypeName()} != ${typeElse.getTypeName()}\n`, | ||
{ path: ctx.file.path, name: ctx.file.name, ref: syntax.ref } | ||
); | ||
|
||
|
||
ctx.block.push(Instruction.if(typeIdx, scopeIf.block, scopeElse?.block)); | ||
|
||
ctx.exited ||= scopeIf.exited && scopeElse.exited; | ||
ctx.block.push(Instruction.unreachable()); | ||
} else { | ||
ctx.block.push(Instruction.if(typeIdx, scopeIf.block)); | ||
} | ||
|
||
return typeIf; | ||
} | ||
|
||
function CompileBlock(ctx: Context, syntax: Syntax.Term_Block, expect?: SolidType): OperandType { | ||
const child = ctx.child(); | ||
child.compile(syntax.value[0].value); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters