Skip to content

Commit

Permalink
Go a basic inference working
Browse files Browse the repository at this point in the history
  • Loading branch information
batiste committed Feb 2, 2019
1 parent 161d723 commit ccac72f
Show file tree
Hide file tree
Showing 17 changed files with 197 additions and 807 deletions.
2 changes: 1 addition & 1 deletion example/index.blop
Expand Up @@ -31,7 +31,7 @@ Index = (state) => {
}
'</style>
<button on={ click: saveStateEvent } class="btn btn-secondary" style={ float: 'right' }>
= 'Save state on the server'
= 'Save locale state on server'
</button>
<h1>
= 'Blop language '
Expand Down
4 changes: 2 additions & 2 deletions example/lib/router.blop
Expand Up @@ -45,7 +45,7 @@ class Router {
route.params = names
this.routes.push(route)
}
def match(path) {
def match(path: string) {
m = null
params = {}
matchedRoute = this.routes.find((route) => {
Expand All @@ -63,7 +63,7 @@ class Router {
return { route: matchedRoute, params: params }
}
}
async def go(path, push=true) {
async def go(path: string, push=true) {
m = this.match(path)
if !m {
console.log('No route for path 'path'')
Expand Down
8 changes: 4 additions & 4 deletions example/lib/state.blop
Expand Up @@ -60,7 +60,7 @@ def create(state, options={ readOnly: false }) {
return new Proxy(
currentState[prop],
handler(currentState[prop],
path + '.' + prop, currentState))
''path'.'prop'', currentState))
}
return obj[prop]
},
Expand All @@ -71,9 +71,9 @@ def create(state, options={ readOnly: false }) {
if protectedProp[prop] {
throw new Error(`You cannot redefine the `prop` property in a proxied state`)
}
modificationTable.push({ path: path + '.' + prop, action: 'set', value })
modificationTable.push({ path: ''path'.'prop'', action: 'set', value })
obj[prop] = value
trigger(path + '.' + prop)
trigger(''path'.'prop'')
return true
},
deleteProperty: def (target, prop) {
Expand All @@ -86,7 +86,7 @@ def create(state, options={ readOnly: false }) {
} else {
return false
}
trigger(path + '.' + prop)
trigger(''path'.'prop'')
return true
}
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -16,7 +16,7 @@
"webpack": "node_modules/webpack/bin/webpack.js",
"webpack-watch": "node_modules/webpack/bin/webpack.js --watch",
"debug": "BLOP_DEBUG=true node_modules/webpack/bin/webpack.js --config webpack.server.js && node dist/server.js",
"linter": "cp {src/parser.js,src/grammar.js,src/tokensDefinition.js,src/backend.js,src/builtin.js} vscode/blop-linter/server/src/ && cd vscode/blop-linter && npm run compile",
"linter": "cp {src/parser.js,src/grammar.js,src/tokensDefinition.js,src/backend.js,src/builtin.js,src/inference.js} vscode/blop-linter/server/src/ && cd vscode/blop-linter && npm run compile",
"link-extensions": "`ln -s $PWD/vscode/blop-linter ~/.vscode/extensions/blop-linter && ln -s $PWD/vscode/blop-syntax-highlighter ~/.vscode/extensions/blop-syntax-highlighter`",
"build": "npm run parser && npm run test && node src/updateAutocompleteFile.js && npm run linter && npm run webpack"
},
Expand Down
4 changes: 2 additions & 2 deletions src/backend.js
Expand Up @@ -507,11 +507,11 @@ backend = {
}
if (node.named['fat-arrow']) {
if (node.named.name) {
checkRedefinition(node.named.name.value, node.named.name)
parentns[node.named.name.value] = {
node,
hoist: false,
token: node.named.name,
annotation: node.named.annotation,
};
output.push(node.named.name.value);
}
Expand All @@ -527,11 +527,11 @@ backend = {
}
output.push('function ');
if (node.named.name) {
checkRedefinition(node.named.name.value, node.named.name)
parentns[node.named.name.value] = {
node,
hoist: false,
token: node.named.name,
annotation: node.named.annotation,
};
output.push(node.named.name.value);
}
Expand Down
2 changes: 1 addition & 1 deletion src/compile.js
Expand Up @@ -24,7 +24,7 @@ function compileFile(source, env = 'webpack', filename = false) {
if (!tree.success) {
utils.displayError(source, stream, tokensDefinition, grammar, tree);
}
check(tree);
// check(tree);

const result = backend.generateCode(tree, stream, source, filename);
if (!result.success) {
Expand Down
24 changes: 10 additions & 14 deletions src/grammar.js
Expand Up @@ -54,9 +54,9 @@ const grammar = {
['name'],
],
'math': [
['(', 'math', ')', 'w', 'operator', 'w', 'exp'],
['(', 'math', ')', 'w', 'math_operator', 'w', 'exp'],
['(', 'math', ')'],
['number', 'w', 'operator', 'w', 'exp'],
['number', 'w', 'math_operator', 'w', 'exp'],
['number'],
],
'assign': [
Expand Down Expand Up @@ -84,12 +84,11 @@ const grammar = {
['name:name', 'annotation?:annotation'],
],
'func_call': [
['(', ')', '.', 'DOTTED_PATH'],
['(', 'newline_and_space?', 'func_call_params', ')', '.', 'DOTTED_PATH'],
['(', ')', 'func_call'],
['(', 'newline_and_space?', 'func_call_params', ')', 'func_call'],
['(', ')'],
['(', 'newline_and_space?', 'func_call_params', ')'],
['(', ')'],
],
'named_func_call': [
['name:name', 'func_call'],
],
'func_call_params': [
['name', '=', 'exp'],
Expand Down Expand Up @@ -190,13 +189,10 @@ const grammar = {
['w', 'name:name'],
],
'operation': [
['operator', 'w', 'exp'],
['==', 'w', 'exp'],
['>=', 'w', 'exp'],
['<=', 'w', 'exp'],
['!=', 'w', 'exp'],
['>', 'w', 'exp'],
['<', 'w', 'exp'],
['math_operator:math_op', 'w', 'exp'],
['boolean_operator:boolean_op', 'w', 'exp'],
['<:boolean_op', 'w', 'exp'],
['>:boolean_op', 'w', 'exp'],
],
'str_expression': [
['str:str', 'inner_str_expression:str_exp'],
Expand Down
81 changes: 73 additions & 8 deletions src/inference.js
@@ -1,4 +1,7 @@

let warnings;
let stream;

function pushInference(node, inference) {
if (!node.inference) {
node.inference = [];
Expand All @@ -13,10 +16,9 @@ const backend = {
for (let i = 0; i < node.children.length; i++) {
visit(node.children[i], node);
}
console.log(node.children);
for (let i = 0; i < node.inference.length; i++) {
if (node.inference[i] !== 'number') {
throw new Error(`Cannot do a math operation with ${node.inference[i]}`);
pushWarning(node, `Cannot do a math operation with ${node.inference[i]}`);
}
}
pushInference(parent, 'number');
Expand All @@ -25,28 +27,73 @@ const backend = {
pushInference(parent, 'number');
},
'name': (node, parent) => {
// todo integrate in the language
if(node.value === 'true' || node.value === 'false') {
pushInference(parent, 'boolean');
return;
}
if (namespace[node.value]) {
pushInference(parent, namespace[node.value].type);
console.log(namespace[node.value], parent);
}
},
'func_def_params': (node, parent) => {
if (node.children) {
for (let i = 0; i < node.children.length; i++) {
visit(node.children[i], node);
}
}
if(node.named.annotation) {
namespace[node.named.name.value] = {
type: node.named.annotation.children[2].value
}
}
},
'operation': (node, parent) => {
if (node.children) {
for (let i = 0; i < node.children.length; i++) {
visit(node.children[i], node);
}
}
if(!node.inference) {
return;
}
if (node.named.math_op && node.inference) {
if (node.inference[0] !== 'number') {
pushWarning(node, `Math operation ${node.named.math_op.value} with ${node.inference[0]}`);
}
if(parent.inference && parent.inference[0] !== 'number') {
pushWarning(node, `Math operation ${node.named.math_op.value} with ${parent.inference[0]}`);
}
pushInference(parent, 'number');
} else {
pushInference(parent, 'boolean');
}
},
'str': (node, parent) => {
pushInference(parent, 'string');
},
'func_call': (node, parent) => {

},
'func_def': (node, parent) => {
if(node.named.named && node.named.annotation) {
namespace[node.named.name.value] = {
type: node.named.annotation.children[2].value
}
}
},
'assign': (node, parent) => {
if (node.children) {
for (let i = 0; i < node.children.length; i++) {
visit(node.children[i], node);
}
}
let name;
if (node.named.name) {
if (node.named.name && node.inference) {
name = node.named.name.value;
} else {
name = node.named.path.children[0].value;
}
if (node.inference) {
namespace[name] = { type: node.inference[0] };
} else {
// name = node.named.path.children[0].value;
}
},
};
Expand All @@ -66,11 +113,29 @@ function visit(node, parent) {
}
}
if (node.inference && parent) {
if(node.inference.length > 1) {
// console.log(node)
}
pushInference(parent, node.inference[0]);
}
}
}

function pushWarning(node, message) {
const error = new Error(message);
const token = stream[node.stream_index];
error.token = token;
warnings.push(error);
}

function inference(node, _stream) {
warnings = [];
stream = _stream;
visit(node);
return warnings;
}

module.exports = {
check: visit,
inference
};

0 comments on commit ccac72f

Please sign in to comment.