UNPKG

@composita/compiler

Version:

Composita language compiler.

84 lines 2.99 kB
import { BooleanDescriptor, CharacterDescriptor, FloatDescriptor, Instruction, IntegerDescriptor, JumpDescriptor, OperationCode, SystemCallDescriptor, TextDescriptor, } from '@composita/il'; var LabelTag; (function (LabelTag) { LabelTag[LabelTag["Tag"] = 0] = "Tag"; })(LabelTag || (LabelTag = {})); export class Label { constructor() { this._labelTag = LabelTag.Tag; } } export class ILAssembler { constructor() { this.targets = new Map(); this.origins = new Map(); this.code = new Array(); } complete() { this.fixLabels(); return this.code; } createLabel() { return new Label(); } setLabel(label) { this.targets.set(label, this.code.length); } fixLabels() { this.origins.forEach((origins, label) => { const target = this.targets.get(label); if (target === undefined) { throw new Error('Cannot branch to unknown label.'); } origins.forEach((origin) => { const instruction = this.code[origin - 1]; if (instruction.code !== OperationCode.Branch && instruction.code !== OperationCode.BranchFalse && instruction.code !== OperationCode.BranchTrue) { throw new Error('Not a jump instruction: ' + instruction.code + ', target: ' + target + ', origin: ' + origin); } this.code[origin - 1].arguments.push(new JumpDescriptor(target - origin)); }); }); } emitLoadInteger(n) { this.emit(OperationCode.LoadConstantInteger, new IntegerDescriptor(n)); } emitLoadFloat(n) { this.emit(OperationCode.LoadConstantFloat, new FloatDescriptor(n)); } emitLoadCharacter(n) { this.emit(OperationCode.LoadConstantCharacter, new CharacterDescriptor(n)); } emitLoadText(n) { this.emit(OperationCode.LoadConstantText, new TextDescriptor(n)); } emitLoadBoolean(n) { this.emit(OperationCode.LoadConstantBoolean, new BooleanDescriptor(n)); } emitJump(opCode, label) { this.emit(opCode); if (!this.origins.has(label)) { this.origins.set(label, new Array()); } this.origins.get(label)?.push(this.code.length); } emitBranch(label) { this.emitJump(OperationCode.Branch, label); } emitBranchFalse(label) { this.emitJump(OperationCode.BranchFalse, label); } emitBranchTrue(label) { this.emitJump(OperationCode.BranchTrue, label); } emitSystemCall(sysCall, numberOfArguments) { const descriptor = new SystemCallDescriptor(sysCall); descriptor.arguments.push(new IntegerDescriptor(numberOfArguments)); this.emit(OperationCode.SystemCall, descriptor); } emit(opCode, ...args) { this.code.push(new Instruction(opCode, ...args)); } } //# sourceMappingURL=il-assembler.js.map