return correct AST until compile error

This commit is contained in:
Shautvast 2024-12-07 23:01:09 +01:00
parent 2de4cac1af
commit 4f574e4198
3 changed files with 69 additions and 25 deletions

View file

@ -29,6 +29,7 @@ import {interpret} from "./interpreter.js";
{v1: "pillars(number, length, shift = 0, direction = UP)", v2: "pillars(3, 10, 0, DOWN);"}, {v1: "pillars(number, length, shift = 0, direction = UP)", v2: "pillars(3, 10, 0, DOWN);"},
{v1: "moving_pillars(number, length, shift = 0, direction = DOWN)", v2: "moving_pillars(3, 10, 0, DOWN);"}, {v1: "moving_pillars(number, length, shift = 0, direction = DOWN)", v2: "moving_pillars(3, 10, 0, DOWN);"},
{v1: "staircase(number, size, direction = DOWN)", v2: "staircase(3, 1, DOWN);"}, {v1: "staircase(number, size, direction = DOWN)", v2: "staircase(3, 1, DOWN);"},
{v1: "repeat([start], end){...}", v2: "repeat(5){\n}"},
]; ];
const slices = {}; const slices = {};
for (let i = 0; i < help.length; i++) { for (let i = 0; i < help.length; i++) {

View file

@ -39,12 +39,12 @@ export function interpret(init_env, code) {
visitParametrizedBlock: (argList, statements) => { visitParametrizedBlock: (argList, statements) => {
let args = argList.map(THIS.evaluate); let args = argList.map(THIS.evaluate);
let start,end; let start, end;
if (args.length===2){ if (args.length === 2) {
start = args[0]; start = args[0];
end = args[1]; end = args[1];
} else { } else {
start =0; start = 0;
end = args[0]; end = args[0];
} }
let previous = THIS.current_environment; let previous = THIS.current_environment;
@ -267,14 +267,8 @@ export function interpret(init_env, code) {
} }
}; };
try {
const statements = parse(code); const statements = parse(code);
for (let i = 0; i < statements.length; i++) { for (let i = 0; i < statements.length; i++) {
THIS.execute(statements[i]); THIS.execute(statements[i]);
} }
} catch (e) {
console.log(e);
}
} }

View file

@ -46,8 +46,14 @@ export function parse(code) {
const parse = () => { const parse = () => {
let statements = []; let statements = [];
while (!is_at_end()) { while (!is_at_end()) {
try {
statements.push(declaration()); statements.push(declaration());
} catch (e) {
console.log(e);
current = tokens.length - 1; // stop compiling
}
} }
return statements; return statements;
} }
@ -66,7 +72,12 @@ export function parse(code) {
initializer = expression(); initializer = expression();
} }
consume(SEMICOLON, "Expected semicolon"); consume(SEMICOLON, "Expected semicolon");
return {class: "var", name:name, initializer: initializer, accept: (visitor) => visitor.visitVariableStatement(name, initializer)}; return {
class: "var",
name: name,
initializer: initializer,
accept: (visitor) => visitor.visitVariableStatement(name, initializer)
};
} }
const statement = () => { const statement = () => {
@ -97,7 +108,7 @@ export function parse(code) {
if (match(MOVING_PILLARS)) { if (match(MOVING_PILLARS)) {
return callStatement("moving_pillars"); return callStatement("moving_pillars");
} }
if (match(REPEAT)){ if (match(REPEAT)) {
return call_block(); return call_block();
} }
if (match(LEFT_BRACE)) { if (match(LEFT_BRACE)) {
@ -130,7 +141,12 @@ export function parse(code) {
if (expr.class === 'Variable') { if (expr.class === 'Variable') {
let name = expr.name; let name = expr.name;
return {class: "assign", var_name: name, init_expr: value, accept: (visitor) => visitor.visitAssignExpr(name, value)}; return {
class: "assign",
var_name: name,
init_expr: value,
accept: (visitor) => visitor.visitAssignExpr(name, value)
};
} }
throw error(equals, "Invalid assignment target."); throw error(equals, "Invalid assignment target.");
@ -150,17 +166,21 @@ export function parse(code) {
return {class: "call", accept: (visitor) => visitor.visitCallStatement(name, args)}; return {class: "call", accept: (visitor) => visitor.visitCallStatement(name, args)};
} }
const call_block = () =>{ const call_block = () => {
const args = arg_expressions(); const args = arg_expressions();
consume(LEFT_BRACE, "Expect block"); consume(LEFT_BRACE, "Expect block");
const action = block(); const action = block();
return {class: "block", accept: (visitor)=> visitor.visitParametrizedBlock(args, action)}; return {class: "block", accept: (visitor) => visitor.visitParametrizedBlock(args, action)};
} }
const expressionStatement = () => { const expressionStatement = () => {
const value = expression(); const value = expression();
consume(SEMICOLON, "Expected semicolon"); consume(SEMICOLON, "Expected semicolon");
return {class: "expressionStatement", expression: value, accept: (visitor) => visitor.visitExpressionStatement(value)}; return {
class: "expressionStatement",
expression: value,
accept: (visitor) => visitor.visitExpressionStatement(value)
};
} }
const block = () => { const block = () => {
@ -178,7 +198,13 @@ export function parse(code) {
let operator = previous(); let operator = previous();
let right = comparison(); let right = comparison();
const left = expr; const left = expr;
expr = {class: "binaryExpr", operator: operator, left: expr, right: right, accept: (visitor) => visitor.visitBinaryExpr(operator, left, right)}; expr = {
class: "binaryExpr",
operator: operator,
left: expr,
right: right,
accept: (visitor) => visitor.visitBinaryExpr(operator, left, right)
};
} }
return expr; return expr;
} }
@ -189,7 +215,13 @@ export function parse(code) {
let operator = previous(); let operator = previous();
let right = term(); let right = term();
const left = expr; const left = expr;
expr = {class: "binaryExpr", operator: operator, left: expr, right: right, accept: (visitor) => visitor.visitBinaryExpr(operator, left, right)}; expr = {
class: "binaryExpr",
operator: operator,
left: expr,
right: right,
accept: (visitor) => visitor.visitBinaryExpr(operator, left, right)
};
} }
return expr; return expr;
} }
@ -200,7 +232,13 @@ export function parse(code) {
let operator = previous(); let operator = previous();
let right = factor(); let right = factor();
const left = expr; const left = expr;
expr = {class: "binaryExpr", operator: operator, left: expr, right: right, accept: (visitor) => visitor.visitBinaryExpr(operator, left, right)}; expr = {
class: "binaryExpr",
operator: operator,
left: expr,
right: right,
accept: (visitor) => visitor.visitBinaryExpr(operator, left, right)
};
} }
return expr; return expr;
} }
@ -211,7 +249,13 @@ export function parse(code) {
let operator = previous(); let operator = previous();
let right = unary(); let right = unary();
const left = expr; const left = expr;
expr = {class: "binaryExpr", operator: operator, left: expr, right: right, accept: (visitor) => visitor.visitBinaryExpr(operator, left, right)}; expr = {
class: "binaryExpr",
operator: operator,
left: expr,
right: right,
accept: (visitor) => visitor.visitBinaryExpr(operator, left, right)
};
} }
return expr; return expr;
} }
@ -220,7 +264,12 @@ export function parse(code) {
if (match(BANG, MINUS)) { if (match(BANG, MINUS)) {
let operator = previous(); let operator = previous();
let right = unary(); let right = unary();
return {class: "unaryExpr", operator: operator, right: right, accept: (visitor) => visitor.visitUnaryExpr(operator, right)}; return {
class: "unaryExpr",
operator: operator,
right: right,
accept: (visitor) => visitor.visitUnaryExpr(operator, right)
};
} }
return primary(); return primary();
} }
@ -235,7 +284,7 @@ export function parse(code) {
if (check(NUMBER)) { if (check(NUMBER)) {
advance(); advance();
let number = parseFloat(previous().literal); let number = parseFloat(previous().literal);
return {class: "number", value:number, accept: (visitor) => visitor.visitLiteralExpr(number)}; return {class: "number", value: number, accept: (visitor) => visitor.visitLiteralExpr(number)};
} }
if (check(STRING)) { if (check(STRING)) {
advance(); advance();