Skip to content

Commit

Permalink
Function declr and dump
Browse files Browse the repository at this point in the history
  • Loading branch information
qti3e committed Aug 5, 2019
1 parent fbdac4c commit cd1f2dc
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 25 deletions.
4 changes: 1 addition & 3 deletions jsc/src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ export class Compiler {
private readonly functions: CompiledData[] = [];
private readonly functionVisitQueue: VisitQueueEntity[] = [];
private main: CompiledData | undefined;
inVarDef = false;

/**
* The returned index can be used in `LdFunction`.
*/
requestVisit(node: estree.Function): number {
const index = this.functionVisitQueue.length;
const entity = { index, node };
Expand Down
47 changes: 39 additions & 8 deletions jsc/src/dump.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import { ByteCode, byteCodeArgSize } from "./bytecode";
import { CompiledData } from "./writer";
import { TextDecoder } from "./text_encoding";

const textDecoder = new TextDecoder();

export function dump(data: CompiledData, sectionName = "MAIN"): string {
let result = "";
const codeU8 = new Uint8Array(data.codeSection);
const cpU8 = new Uint8Array(data.constantPool);
const scopeU8 = new Uint8Array(data.scope);
const sectionTitle = "SECTION #" + sectionName;

result += ("<-------" + sectionTitle).padEnd(80, "-") + "\n";
result += ("+>" + sectionTitle).padEnd(80, "-") + "\n";

for (let i = 0; i < codeU8.length; ++i) {
const bytecode: ByteCode = codeU8[i] as ByteCode;
const argSize = byteCodeArgSize[bytecode] || 0;

let line = " ";
line += hex2str(i, "0000");
line += hex2str(i, "00000000");
line += " | ";

for (let j = 0; j <= argSize; ++j) {
Expand All @@ -32,7 +36,32 @@ export function dump(data: CompiledData, sectionName = "MAIN"): string {
result += line + "\n";
}

result += " +------CONSTANT POOL".padEnd(80, "-") + "\n";
result += " +------SCOPE".padEnd(80, "-") + "\n";

const scopeItemsLength = readUint16(scopeU8, 0);
let scopeCursor = 2;
if (scopeItemsLength === 0) {
result += "|".padStart(11) + "EMPTY".padStart(34).padEnd(68) + "|\n";
}

for (let i = 0; i < scopeItemsLength; ++i) {
let line = "";
const isFunction = scopeU8[scopeCursor];
const strLen = readUint16(scopeU8, scopeCursor + 1);
const start = scopeCursor + 3;
const name = textDecoder.decode(scopeU8.slice(start, start + strLen));
scopeCursor += 2 + strLen;

line += "DEF " + name;
if (isFunction) {
const fnId = readUint16(scopeU8, scopeCursor);
line += " FUNCTION(" + hex2str(fnId) + ")";
scopeCursor += 2;
}
result += ("| ".padStart(12) + line).padEnd(79) + "|\n";
}

result += " +----CONSTANT POOL".padEnd(80, "-") + "\n";

for (let i = 0; i < cpU8.length; i += 16) {
let line = " ";
Expand All @@ -58,14 +87,16 @@ export function dump(data: CompiledData, sectionName = "MAIN"): string {
}

if (cpU8.length === 0) {
result += "EMPTY".padStart(40).padEnd(79) + "|\n";
result += "|".padStart(11) + "EMPTY".padStart(34).padEnd(68) + "|\n";
}

result += " " + (sectionTitle + "->").padStart(70, "-");

return result;
return result.slice(0, result.length - 1);
}

function hex2str(num: number, pad = "00"): string {
return "0x" + (pad + num.toString(16)).slice(-pad.length);
return (pad + num.toString(16)).slice(-pad.length);
}

function readUint16(u8: Uint8Array, index: number): number {
return (u8[index] << 8) + u8[index + 1];
}
6 changes: 4 additions & 2 deletions jsc/src/play.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import { dump } from "./dump";

function main() {
const source = `
void x;
a - -0;
function abc() {
}
abc * 0;
`;

const context = new Compiler();
Expand Down
8 changes: 6 additions & 2 deletions jsc/src/scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,19 @@ export class Scope {

addFunction(name: string, id: number): void {
this.buffer.writeUint16(++this.num, 0);
this.buffer.put(0);
this.buffer.put(1);
// TODO(qti3e) This is wrong... name.length is not the
// same as number of bytes.
this.buffer.writeUint16(name.length);
this.buffer.writeString(name);
this.buffer.writeUint16(id);
}

addVariable(name: string): void {
this.buffer.writeUint16(++this.num, 0);
this.buffer.put(1);
this.buffer.put(0);
// TODO(qti3e) This is wrong... name.length is not the
// same as number of bytes.
this.buffer.writeUint16(name.length);
this.buffer.writeString(name);
}
Expand Down
29 changes: 19 additions & 10 deletions jsc/src/visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,24 @@ export function visit(writer: Writer, node: estree.Node): void {
let jmp1: Jump;

switch (node.type) {
case "ExpressionStatement":
case "ExpressionStatement": {
visit(writer, node.expression);
break;
}

case "ThisExpression":
case "ThisExpression": {
writer.write(ByteCode.LdThis);
break;
}

case "BinaryExpression":
case "BinaryExpression": {
visit(writer, node.left);
visit(writer, node.right);
binaryOperator(writer, node.operator);
break;
}

case "LogicalExpression":
case "LogicalExpression": {
visit(writer, node.left);
jmp1 = writer.jmp(
node.operator == "||" ? ByteCode.JmpTruePeek : ByteCode.JmpFalsePeek
Expand All @@ -29,13 +32,15 @@ export function visit(writer: Writer, node: estree.Node): void {
visit(writer, node.right);
jmp1.here();
break;
}

case "UnaryExpression":
case "UnaryExpression": {
visit(writer, node.argument);
unaryOperator(writer, node.operator);
break;
}

case "Literal":
case "Literal": {
switch (node.value) {
case true:
writer.write(ByteCode.LdTrue);
Expand Down Expand Up @@ -63,15 +68,19 @@ export function visit(writer: Writer, node: estree.Node): void {
writer.write(ByteCode.TODO);
}
break;
}

case "Identifier":
case "Identifier": {
writer.write(ByteCode.Named, node.name);
break;
}

case "FunctionDeclaration":
// Function Declaration is already seen due to how hoisting
// is implemented.
case "FunctionDeclaration": {
const index = writer.compiler.requestVisit(node);
writer.scope.addFunction(node.id!.name, index);
// No instruction is needed.
break;
}

default:
// TODO(qti3e)
Expand Down

0 comments on commit cd1f2dc

Please sign in to comment.