Skip to content

Commit

Permalink
+struct zeroing with trailing 0
Browse files Browse the repository at this point in the history
  • Loading branch information
AjaniBilby committed Mar 21, 2024
1 parent bd653f5 commit 9072edc
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
*.sa linguist-language=Salient
*.sa linguist-language=Salient eol=lf
* text=auto eol=lf
2 changes: 1 addition & 1 deletion source/compiler/codegen/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { File } from "~/compiler/file.ts";
import * as banned from "~/compiler/codegen/banned.ts";
import Structure from "~/compiler/structure.ts";
import { BasePointerType, LinearType, OperandType, SolidType, IsRuntimeType, IsSolidType } from "~/compiler/codegen/expression/type.ts";
import { IntrinsicType, IntrinsicValue, none, never, i32 } from "~/compiler/intrinsic.ts";
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";
Expand Down
66 changes: 51 additions & 15 deletions source/compiler/codegen/expression/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ 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 { MaybeSingularExprArg } from "~/compiler/codegen/expression/helper.ts";
import { ResolveLinearType } from "~/compiler/codegen/expression/helper.ts";
import { CompileExpr } from "~/compiler/codegen/expression/index.ts";
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";
Expand All @@ -26,19 +29,35 @@ export function StructBuilder(ctx: Context, syntax: Syntax.Term_Container, expec
}

function NestedStructBuilder(ctx: Context, linear: LinearType, syntax: Syntax.Term_Container) {
function* iterator() {
function* iterator(skipLast = false) {
const base = syntax.value[0].value[0];
if (!base) return;

// Skipping the last is the first in this case
if (skipLast && base.value[1].value.length === 0) return;

yield base.value[0]; // first
for (const next of base.value[1].value) yield next.value[0]; // comma chained

const length = base.value[1].value.length - ( skipLast ? 1 : 0 );
for (let i=0; i<length; i++) {
const next = base.value[1].value[i];
yield next.value[0];
}

return;
}

for (const item of iterator()) {
const zeroed = ShouldZero(syntax);
if (zeroed) {
ResolveLinearType(ctx, linear, syntax.ref, false); // address
ctx.block.push(Instruction.const.i32(0)); // value
ctx.block.push(Instruction.const.i32(linear.getBaseType().size)); // size
ctx.block.push(Instruction.fill());
}

for (const item of iterator(zeroed)) {
const elm = item.value[0];
if (elm.type !== "container_map") {
if (elm.type === "container_value") {
console.error(
`${colors.red("Error")}: Unexpected array value as struct member\n`
+ SourceView(ctx.file.path, ctx.file.name, elm.ref)
Expand Down Expand Up @@ -68,24 +87,41 @@ function NestedStructBuilder(ctx: Context, linear: LinearType, syntax: Syntax.Te
Assign(ctx, target, expr, elm.ref);
}

// All non inited attributes have been filled with zero
if (zeroed) linear.markDefined();

return linear;
}

function MaybeNestedContainer(syntax: Syntax.Term_Expr) {
const noInfix = syntax.value[1].value.length == 0;
if (!noInfix) return null;
function ShouldZero(syntax: Syntax.Term_Container) {
const elms = syntax.value[0].value[0];
if (!elms) return false;

const expr_arg = syntax.value[0];
const expr_val = expr_arg.value[1];
if (expr_val.value[0].type != "container") return null;
const chain = elms.value[1];
const lastI = chain.value.length-1;

const hasPrefix = expr_arg.value[0].value.length != 0;
if (hasPrefix) return null;
const last_item = lastI > 0
? chain.value[lastI].value[0].value[0]
: elms.value[0].value[0];

const hasPostfix = expr_arg.value[2].value.length != 0;
if (hasPostfix) return null;
if (last_item.type === "container_map") return false;

const expr_arg = MaybeSingularExprArg(last_item.value[0]);
if (!expr_arg) return false;
if (expr_arg.type !== "constant") return false;

const constant = expr_arg.value[0];
if (constant.type !== "integer") return false;

return constant.value[0].value === "0";
}

function MaybeNestedContainer(syntax: Syntax.Term_Expr) {
const expr_val = MaybeSingularExprArg(syntax);
if (expr_val === null) return null;
if (expr_val.type != "container") return null;

return expr_val.value[0];
return expr_val;
}


Expand Down
22 changes: 21 additions & 1 deletion source/compiler/codegen/expression/helper.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
import type * as Syntax from "~/bnf/syntax.d.ts";

import { AssertUnreachable, LatentOffset, Panic } from "~/helper.ts";
import { IntrinsicType, IntrinsicValue } from "~/compiler/intrinsic.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";


export function MaybeSingularExprArg(syntax: Syntax.Term_Expr) {
const noInfix = syntax.value[1].value.length == 0;
if (!noInfix) return null;

const expr_arg = syntax.value[0];
const expr_val = expr_arg.value[1];

const hasPrefix = expr_arg.value[0].value.length != 0;
if (hasPrefix) return null;

const hasPostfix = expr_arg.value[2].value.length != 0;
if (hasPostfix) return null;

return expr_val.value[0];
}


export function Store(ctx: Context, type: IntrinsicType, offset: number | LatentOffset) {
switch (type.name) {
case "u32": case "i32": ctx.block.push(Instruction.i32.store(offset, 0)); break;
Expand Down
4 changes: 2 additions & 2 deletions source/compiler/codegen/expression/operand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ export function CompileArg(ctx: Context, syntax: Syntax.Term_Expr_arg, expect?:
}

function CompileContainer(ctx: Context, syntax: Syntax.Term_Container, expect?: SolidType): OperandType {
if (expect instanceof Structure) return StructBuilder(ctx, syntax, expect);

switch (syntax.value[0].value[0]?.value[0].value[0].type) {
case "container_map": return StructBuilder(ctx, syntax, expect);
case "container_value": return ArrayBuilder(ctx, syntax, expect);
}

if (expect instanceof Structure) return StructBuilder(ctx, syntax, expect);

Panic(
`Unable to determine container type\n`, {
path: ctx.file.path, name: ctx.file.name, ref: syntax.ref
Expand Down
1 change: 1 addition & 0 deletions source/wasm/instruction/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ const wrapper = {
noop : () => shared_NoOp,

copy: memFuncs.copy,
fill: memFuncs.fill,

block: (typeIdx: number, n?: Any[]) => new Block(typeIdx, n),
if : (typeIdx: number, t?: Any[], f?: Any[]) => new IfBlock(typeIdx, t, f),
Expand Down
19 changes: 18 additions & 1 deletion source/wasm/instruction/memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,22 @@ export class MemoryCopy {
}
}

export class MemoryFill {
memoryIdx: number;

constructor(memoryIdx: Byte) {
this.memoryIdx = memoryIdx;
}

toBinary(): Byte[] {
return [
0xFC,
...EncodeU32(11),
this.memoryIdx,
]
}
}

const wrapper = {
i32: {
load : (offset: number | LatentOffset, align: number) => new MemoryRegister(Type.i32Load, offset, align),
Expand Down Expand Up @@ -114,6 +130,7 @@ const wrapper = {
store : (offset: number | LatentOffset, align: number) => new MemoryRegister(Type.f64Store, offset, align),
},

copy: (fromMemoryIdx = 0, toMemoryIdx = 0) => new MemoryCopy(fromMemoryIdx, toMemoryIdx)
copy: (fromMemoryIdx = 0, toMemoryIdx = 0) => new MemoryCopy(fromMemoryIdx, toMemoryIdx),
fill: (memoryIdx = 0) => new MemoryFill(memoryIdx),
}
export default wrapper;

0 comments on commit 9072edc

Please sign in to comment.