Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use Pratt's parser for expressions in the {log} block #275

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion hsp/compiler/jsgenerator/processors.js
Expand Up @@ -141,7 +141,7 @@ exports["log"] = function (node, walker) {
indexes.push(expr.exprIdx);
code.push(expr.code);
}
return ["n.log({", code.join(","), "},[", indexes.join(','), "],'", walker.fileName, "','", walker.dirPath, "',",node.line, ",", node.column, ")"].join('');
return ["n.log({", code.join(","), "},'", walker.fileName, "','", walker.dirPath, "',",node.line, ",", node.column, ")"].join('');
};

/**
Expand Down
4 changes: 2 additions & 2 deletions hsp/compiler/parser/hspblocks.pegjs
Expand Up @@ -221,15 +221,15 @@ HTMLAttributeChar // TODO look at W3C specs
/ [^{\"\n\r]

LogBlock
= "{" _ "log " _ first:HPipeExpression _ next:("," _ HPipeExpression)* _"}" EOS?
= "{" _ "log " _ first:CoreExpText _ next:("," _ CoreExpText)* _"}" EOS?
{
var exprs=[first];
if (next) {
for (var i=0, sz=next.length;sz>i;i++) {
exprs.push(next[i][2]);
}
}
return {type:"log",exprs:exprs, line:line, column:column};
return {type:"log", exprs:exprs, line:line, column:column};
}

LetBlock
Expand Down
8 changes: 2 additions & 6 deletions hsp/compiler/treebuilder/syntaxTree.js
Expand Up @@ -253,14 +253,10 @@ var SyntaxTree = klass({
* @return {Integer} the index of the block where the function stopped or -1 if all blocks have been handled.
*/
__log : function (index, blocks, out) {
var node = new Node("log"), block = blocks[index], exprs = [];
var node = new Node("log"), block = blocks[index];
node.line = block.line;
node.column = block.column;
for (var i = 0; i < block.exprs.length; i++) {
var expr = new HExpression(block.exprs[i], this);
exprs[i] = expr.getSyntaxTree();
}
node.exprs = exprs;
node.exprs = block.exprs;
out.push(node);
return index;
},
Expand Down
3 changes: 2 additions & 1 deletion hsp/expressions/manipulator.js
Expand Up @@ -59,6 +59,7 @@ module.exports = function(input, inputTree) {
evaluator(tree.l, scope)[evaluator(tree.r, scope)] = newValue;
}
},
isAssignable : isAssignable
isAssignable: isAssignable,
isMultiStatement: tree instanceof Array
};
};
12 changes: 9 additions & 3 deletions hsp/expressions/parser.js
Expand Up @@ -284,16 +284,22 @@ function expression(rbp) {
* @return {Object} - parsed AST
*/
module.exports = function (input) {
var expr, exprs = [];

tokens = lexer(input);
token = undefined;
tokenIdx = 0;

if (tokens.length) {
advance(); //get the first token
var expr = expression(0);
advance('(end)'); //make sure that we are at the end of an expression
return expr;
while(token.id !== '(end)') {
expr = expression(0);
exprs.push(expr);
if (token.v === ',') {
advance(',');
}
}
return exprs.length === 1 ? exprs[0] : exprs;
} else {
return {f: 0, a: 'literal', v: undefined};
}
Expand Down
18 changes: 7 additions & 11 deletions hsp/rt/$log.js
Expand Up @@ -31,7 +31,7 @@ var LogNode = klass({
* @param {Integer} line the line number
* @param {Integer} column the column number
*/
$constructor : function (exps, args, file, dir, line, column) {
$constructor : function (exps, file, dir, line, column) {
TNode.$constructor.call(this, exps);
this.file='';
var r=file.match(/[^\/\\]+$/);
Expand All @@ -41,7 +41,6 @@ var LogNode = klass({
this.dir=dir;
this.line=line;
this.column=column;
this.args = args;
},

/**
Expand All @@ -56,15 +55,12 @@ var LogNode = klass({
* Process the information to be logged and push it to the log output (browser console by default)
*/
processLog : function () {
var itms=[], args=this.args, eh=this.eh, v;
if (this.args) {
for (var i=0, sz=args.length;sz>i;i++) {
v=eh.getValue(args[i], this.vscope, undefined);
itms.push(v);
}
itms.push({type:'debug',file:this.file,dir:this.dir,line:this.line,column:this.column});
log.apply(null,itms);
}
var exp=this.eh.getExpr(1); //there is only one expression for the log block
var v = exp.getValue(this.vscope, undefined);
var itms = exp.isMultiStatement ? v : [v];

itms.push({type:'debug',file:this.file,dir:this.dir,line:this.line,column:this.column});
log.apply(null,itms);
},

/**
Expand Down
1 change: 1 addition & 0 deletions hsp/rt/exphandler.js
Expand Up @@ -138,6 +138,7 @@ var PrattExpr = klass({
this.ast = exparser(desc[1]);
this.bound = exidentifiers(this.ast).length > 0;
this.manipulator = exmanipulator(desc[1], this.ast);
this.isMultiStatement = this.manipulator.isMultiStatement;
},

getValue : function (vscope, eh, defvalue) {
Expand Down
52 changes: 5 additions & 47 deletions test/compiler/samples/log1.txt
Expand Up @@ -15,32 +15,11 @@
"type": "log",
"exprs": [
{
"type": "expression",
"category": "string",
"value": "here",
"code": "here",
"expType": "expression",
"category": "jsexptext",
"value": '"here", person, scope',
"line": 3,
"column": 8
},
{
"type": "Variable",
"name": "person",
"code": "person",
"category": "jsexpression",
"expType": "Variable",
"line": 3,
"column": 16
},
{
"type": "Variable",
"name": "scope",
"code": "scope",
"category": "jsexpression",
"expType": "Variable",
"line": 3,
"column": 24
}
],
"line": 3,
"column": 3
Expand All @@ -64,31 +43,10 @@
"column": 3,
"exprs": [
{
"type": "expression",
"category": "string",
"value": "here",
"code": "here",
"expType": "expression",
"category": "jsexptext",
"value": '"here", person, scope',
"line": 3,
"column": 8
},
{
"type": "expression",
"category": "objectref",
"path": [
"person"
],
"line": 3,
"column": 16
},
{
"type": "expression",
"category": "objectref",
"path": [
"scope"
],
"line": 3,
"column": 24
}
]
},
Expand All @@ -101,6 +59,6 @@
##### Template Code
test=[__s,
n.$text(0,["Hello "]),
n.log({e1:[5,"here"],e2:[1,1,"person"],e3:[1,1,"scope"]},[1,2,3],'log1','',3,3),
n.log({e1:[9,"\"here\", person, scope"]},'log1','',3,3),
n.$text(0,["World"])
]
5 changes: 1 addition & 4 deletions test/compiler/samples/log2.txt
Expand Up @@ -14,11 +14,8 @@
test=[__s,
n.$text(0,["Advanced log: "]),
n.log({
e1:[6,function(a0) {return (3 + (4 * a0));},2],
e2:[1,2,"person","age"],
e3:[1,3,"person","foo","bar"]
e1:[9,"3+4*person.age, person.foo.bar"]
},
[1,3],
'log2',
'',
3,
Expand Down
13 changes: 13 additions & 0 deletions test/expressions/manipulator.spec.js
Expand Up @@ -259,6 +259,19 @@ describe('getValue', function () {
expect(expression("{foo: 'bar', foo2: 'baz'}").getValue({})).to.eql({foo: 'bar', foo2: 'baz'});
expect(expression("{foo: {foo2: 'baz'}}").getValue({})).to.eql({foo: {foo2: 'baz'}});
});

describe('multiple statements in an expression', function () {

it('should allow multiple comma-separated statements', function () {
expect(expression("foo, bar").getValue({foo: 'foo', bar: 'bar'}))
.to.eql(['foo', 'bar']);
});

it('should mark expressions as multi-statement', function () {
expect(expression("foo, bar").isMultiStatement).to.be.ok();
expect(expression("foo").isMultiStatement).to.not.be.ok();
});
});
});

describe('forgiving evaluation of expressions', function () {
Expand Down