diff --git a/.gitattributes b/.gitattributes index ee38dad..86404ce 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,2 @@ -*.sa linguist-language=Salient +*.sa linguist-language=Salient eol=lf * text=auto eol=lf \ No newline at end of file diff --git a/source/compiler/codegen/context.ts b/source/compiler/codegen/context.ts index 6b0b8d6..44939b1 100644 --- a/source/compiler/codegen/context.ts +++ b/source/compiler/codegen/context.ts @@ -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"; diff --git a/source/compiler/codegen/expression/container.ts b/source/compiler/codegen/expression/container.ts index 5316f63..17412cb 100644 --- a/source/compiler/codegen/expression/container.ts +++ b/source/compiler/codegen/expression/container.ts @@ -3,7 +3,10 @@ import * as colors from "https://deno.land/std@0.201.0/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"; @@ -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 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; } diff --git a/source/compiler/codegen/expression/helper.ts b/source/compiler/codegen/expression/helper.ts index 5eefcb7..4308483 100644 --- a/source/compiler/codegen/expression/helper.ts +++ b/source/compiler/codegen/expression/helper.ts @@ -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; diff --git a/source/compiler/codegen/expression/operand.ts b/source/compiler/codegen/expression/operand.ts index 88da39f..16e89b5 100644 --- a/source/compiler/codegen/expression/operand.ts +++ b/source/compiler/codegen/expression/operand.ts @@ -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 diff --git a/source/wasm/instruction/index.ts b/source/wasm/instruction/index.ts index 96d39c5..d43bc60 100644 --- a/source/wasm/instruction/index.ts +++ b/source/wasm/instruction/index.ts @@ -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), diff --git a/source/wasm/instruction/memory.ts b/source/wasm/instruction/memory.ts index 159fdd4..443d1ed 100644 --- a/source/wasm/instruction/memory.ts +++ b/source/wasm/instruction/memory.ts @@ -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), @@ -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; \ No newline at end of file