Skip to content

Commit

Permalink
Refactor builtin functions for extension.
Browse files Browse the repository at this point in the history
  • Loading branch information
twodee committed Jul 4, 2024
1 parent 84db89c commit 79f27cd
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 106 deletions.
19 changes: 11 additions & 8 deletions src/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,17 @@ export function createExecutable(tree) {
case NODETYPES.INPUT:
return new Praxly_input(tree);

case NODETYPES.RANDOM:
return new Praxly_random(tree);

case NODETYPES.RANDOM_INT:
return new Praxly_random_int(createExecutable(tree.max), tree);

case NODETYPES.RANDOM_SEED:
return new Praxly_random_seed(createExecutable(tree.seed), tree);
case NODETYPES.BUILTIN_FUNCTION_CALL: {
if (tree.name === 'random') {
return new Praxly_random(tree);
} else if (tree.name === 'randomInt') {
return new Praxly_random_int(createExecutable(tree.parameters[0]), tree);
} else if (tree.name === 'randomSeed') {
return new Praxly_random_seed(createExecutable(tree.parameters[0]), tree);
} else {
throw new Error('unknown builtin function');
}
}

case NODETYPES.SPECIAL_STRING_FUNCCALL:
var args = [];
Expand Down
18 changes: 13 additions & 5 deletions src/blocks2tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,26 +81,34 @@ export const makeGenerator = () => {

praxlyGenerator['praxly_random_block'] = (block) => {
return {
name: 'random',
blockID: block.id,
type: NODETYPES.RANDOM,
type: NODETYPES.BUILTIN_FUNCTION_CALL,
parameters: [],
};
}

praxlyGenerator['praxly_random_int_block'] = (block) => {
const expression = block.getInputTargetBlock('MAX');
return {
name: 'randomInt',
blockID: block.id,
type: NODETYPES.RANDOM_INT,
max: praxlyGenerator[expression.type](expression),
type: NODETYPES.BUILTIN_FUNCTION_CALL,
parameters: [
praxlyGenerator[expression.type](expression),
],
};
}

praxlyGenerator['praxly_random_seed_block'] = (block) => {
const expression = block.getInputTargetBlock('SEED');
return {
name: 'randomSeed',
blockID: block.id,
type: NODETYPES.RANDOM_SEED,
seed: praxlyGenerator[expression.type](expression),
type: NODETYPES.BUILTIN_FUNCTION_CALL,
parameters: [
praxlyGenerator[expression.type](expression),
],
};
}

Expand Down
4 changes: 1 addition & 3 deletions src/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@ export const NODETYPES = {
...TYPES,
PRINT: "PRINT",
PRINTLN: "PRINTLN",
RANDOM: "RANDOM",
RANDOM_INT: "RANDOM_INT",
RANDOM_SEED: "RANDOM_SEED",
BUILTIN_FUNCTION_CALL: "BUILTIN_FUNCTION_CALL",
INPUT: "INPUT",
CODEBLOCK: "CODEBLOCK",
PROGRAM: "PROGRAM",
Expand Down
106 changes: 41 additions & 65 deletions src/text2tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -600,48 +600,10 @@ class Parser {
this.tokens[this.i].token_type = NODETYPES.INPUT;
this.advance();
return this.literalNode_new(this.tokens[this.i - 1]);
case 'random': {
const randomToken = this.advance();
if (this.has('(')) {
this.advance();
if (this.has(')')) {
const rightParenthesisToken = this.advance();
return {
blockID: "code",
line,
type: NODETYPES.RANDOM,
startIndex: randomToken.startIndex,
endIndex: rightParenthesisToken.endIndex,
};
} else {
textError('parsing', 'did not detect right parenthesis', line);
}
} else {
textError('parsing', 'did not detect left parenthesis', line);
}
}
case 'randomInt': {
const randomToken = this.advance();
if (this.has('(')) {
this.advance();
const max = this.parse_expression(9);
if (this.has(')')) {
const rightParenthesisToken = this.advance();
return {
blockID: "code",
line,
max,
type: NODETYPES.RANDOM_INT,
startIndex: randomToken.startIndex,
endIndex: rightParenthesisToken.endIndex,
};
} else {
textError('parsing', 'did not detect right parenthesis', line);
}
} else {
textError('parsing', 'did not detect left parenthesis', line);
}
}
case 'random':
case 'randomInt':
return this.parse_builtin_function_call(line);

case NODETYPES.BOOLEAN:
this.advance();
return this.literalNode_new(this.tokens[this.i - 1]);
Expand Down Expand Up @@ -735,8 +697,42 @@ class Parser {
}
}

parse_builtin_function_call(line) {
// Assumes identifier token is up.
const nameToken = this.advance();
if (this.has('(')) {
this.advance();

// Expect 0 or more parameters.
const parameters = [];
if (this.hasNot(')')) {
const parameter = this.parse_expression(9);
parameters.push(parameter);
while (this.has(',')) {
this.advance();
const parameter = this.parse_expression(9);
parameters.push(parameter);
}
}

if (this.has(')')) {
const rightParenthesisToken = this.advance();
return {
blockID: "code",
name: nameToken.value,
line,
parameters,
type: NODETYPES.BUILTIN_FUNCTION_CALL,
startIndex: nameToken.startIndex,
endIndex: rightParenthesisToken.endIndex,
};
} else {
textError('parsing', 'did not detect right parenthesis', line);
}
} else {
textError('parsing', 'did not detect left parenthesis', line);
}
}

parse_location() {
var result = {
Expand Down Expand Up @@ -1056,31 +1052,11 @@ class Parser {
}

else if (this.has("randomSeed")) {
const randomToken = this.advance();
if (this.has('(')) {
const node = this.parse_builtin_function_call(line);
if (this.has(';')) {
this.advance();
const seed = this.parse_expression(9);
if (this.has(')')) {
const rightParenthesisToken = this.advance();

if (this.has(';')) {
this.advance();
}

return {
blockID: "code",
line,
seed,
type: NODETYPES.RANDOM_SEED,
startIndex: randomToken.startIndex,
endIndex: rightParenthesisToken.endIndex,
};
} else {
textError('parsing', 'did not detect right parenthesis', line);
}
} else {
textError('parsing', 'did not detect left parenthesis', line);
}
return node;
}

else if (this.has("return")) {
Expand Down
27 changes: 12 additions & 15 deletions src/tree2blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,21 +130,18 @@ export const tree2blocks = (workspace, node) => {
result = workspace.newBlock('praxly_input_block');
break;

case NODETYPES.RANDOM:
result = workspace.newBlock('praxly_random_block');
break;

case NODETYPES.RANDOM_INT: {
result = workspace.newBlock('praxly_random_int_block');
const child = tree2blocks(workspace, node?.max);
result.getInput('MAX').connection.connect(child?.outputConnection);
break;
}

case NODETYPES.RANDOM_SEED: {
result = workspace.newBlock('praxly_random_seed_block');
const child = tree2blocks(workspace, node?.seed);
result.getInput('SEED').connection.connect(child?.outputConnection);
case NODETYPES.BUILTIN_FUNCTION_CALL: {
if (node.name === 'random') {
result = workspace.newBlock('praxly_random_block');
} else if (node.name === 'randomInt') {
result = workspace.newBlock('praxly_random_int_block');
const child = tree2blocks(workspace, node?.parameters[0]);
result.getInput('MAX').connection.connect(child?.outputConnection);
} else if (node.name === 'randomSeed') {
result = workspace.newBlock('praxly_random_seed_block');
const child = tree2blocks(workspace, node?.parameters[0]);
result.getInput('SEED').connection.connect(child?.outputConnection);
}
break;
}

Expand Down
21 changes: 11 additions & 10 deletions src/tree2text.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,16 +164,17 @@ export const tree2text = (node, indentation) => {
case NODETYPES.INPUT:
return "input";

case NODETYPES.RANDOM:
return "random()";

case NODETYPES.RANDOM_INT:
const max = tree2text(node.max, indentation);
return `randomInt(${max})`;

case NODETYPES.RANDOM_SEED:
const seed = tree2text(node.seed, indentation);
return `randomSeed(${seed})\n`;
case NODETYPES.BUILTIN_FUNCTION_CALL: {
if (node.name === 'random') {
return "random()";
} else if (node.name === 'randomInt') {
const max = tree2text(node.parameters[0], indentation);
return `randomInt(${max})`;
} else if (node.name === 'randomSeed') {
const seed = tree2text(node.parameters[0], indentation);
return `randomSeed(${seed})\n`;
}
}

case NODETYPES.RETURN:
var result = ' '.repeat(indentation) + "return ";
Expand Down

0 comments on commit 79f27cd

Please sign in to comment.