Skip to content

Commit

Permalink
function prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
felixhao28 committed Jul 27, 2015
1 parent dd4f71e commit 26e7630
Show file tree
Hide file tree
Showing 14 changed files with 2,929 additions and 2,734 deletions.
1 change: 0 additions & 1 deletion demo/debug.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ argv = require("minimist") process.argv.slice(2)

config = {}

console.log JSON.stringify(argv)
if process.argv.length > 2
testName = argv._[0];
if argv.d or argv.debug
Expand Down
2 changes: 0 additions & 2 deletions demo/debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ argv = require("minimist")(process.argv.slice(2));

config = {};

console.log(JSON.stringify(argv));

if (process.argv.length > 2) {
testName = argv._[0];
if (argv.d || argv.debug) {
Expand Down
2,724 changes: 1,394 additions & 1,330 deletions dist/JSCPP.js

Large diffs are not rendered by default.

2,536 changes: 1,273 additions & 1,263 deletions lib/ast.js

Large diffs are not rendered by default.

53 changes: 26 additions & 27 deletions lib/interpreter.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,35 +103,35 @@ Interpreter = function(rt) {
j = 0;
while (j < dec.Declarator.right.length) {
dim = dec.Declarator.right[j];
if (dim.type !== "DirectDeclarator_modifier_array") {
rt.raiseException("is interp really an array initialization?");
}
if (dim.Expression !== null) {
dim = rt.cast(rt.intTypeLiteral, (yield* interp.visit(interp, dim.Expression, param))).v;
} else if (j > 0) {
rt.raiseException("multidimensional array must have bounds for all dimensions except the first");
} else {
if (init.type === "Initializer_expr") {
initializer = (yield* interp.visit(interp, init, param));
if (rt.isTypeEqualTo(type, rt.charTypeLiteral) && rt.isArrayType(initializer.t) && rt.isTypeEqualTo(initializer.t.eleType, rt.charTypeLiteral)) {
dim = initializer.v.target.length;
init = {
type: "Initializer_array",
Initializers: initializer.v.target.map(function(e) {
return {
type: "Initializer_expr",
shorthand: e
};
})
};
switch (dim.type) {
case "DirectDeclarator_modifier_array":
if (dim.Expression !== null) {
dim = rt.cast(rt.intTypeLiteral, (yield* interp.visit(interp, dim.Expression, param))).v;
} else if (j > 0) {
rt.raiseException("multidimensional array must have bounds for all dimensions except the first");
} else {
rt.raiseException("cannot initialize an array to " + rt.makeValString(initializer));
if (init.type === "Initializer_expr") {
initializer = (yield* interp.visit(interp, init, param));
if (rt.isTypeEqualTo(type, rt.charTypeLiteral) && rt.isArrayType(initializer.t) && rt.isTypeEqualTo(initializer.t.eleType, rt.charTypeLiteral)) {
dim = initializer.v.target.length;
init = {
type: "Initializer_array",
Initializers: initializer.v.target.map(function(e) {
return {
type: "Initializer_expr",
shorthand: e
};
})
};
} else {
rt.raiseException("cannot initialize an array to " + rt.makeValString(initializer));
}
} else {
dim = init.Initializers.length;
}
}
} else {
dim = init.Initializers.length;
}
dimensions.push(dim);
}
dimensions.push(dim);
j++;
}
init = (yield* interp.arrayInit(dimensions, init, 0, type, param));
Expand Down Expand Up @@ -894,7 +894,6 @@ Interpreter.prototype.arrayInit = function*(dimensions, init, level, type, param
if (init && init.type !== "Initializer_expr") {
this.rt.raiseException("dimensions do not agree, too few initializers");
}
initval;
if (init) {
if ("shorthand" in init) {
initval = init.shorthand;
Expand Down
135 changes: 95 additions & 40 deletions lib/rt.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,34 +114,38 @@ CRuntime.prototype.getMember = function(l, r) {
CRuntime.prototype.defFunc = function(lt, name, retType, argTypes, argNames, stmts, interp) {
var f, rt;
rt = this;
f = function*() {
var _this, args, ret, rt;
rt = arguments[0], _this = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : [];
rt.enterScope("function " + name);
argNames.forEach(function(v, i) {
rt.defVar(v, argTypes[i], args[i]);
});
ret = (yield* interp.run(stmts, {
scope: "function"
}));
if (!rt.isTypeEqualTo(retType, rt.voidTypeLiteral)) {
if (ret instanceof Array && ret[0] === "return") {
ret = rt.cast(retType, ret[1]);
if (stmts != null) {
f = function*() {
var _this, args, ret, rt;
rt = arguments[0], _this = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : [];
rt.enterScope("function " + name);
argNames.forEach(function(v, i) {
rt.defVar(v, argTypes[i], args[i]);
});
ret = (yield* interp.run(stmts, {
scope: "function"
}));
if (!rt.isTypeEqualTo(retType, rt.voidTypeLiteral)) {
if (ret instanceof Array && ret[0] === "return") {
ret = rt.cast(retType, ret[1]);
} else {
rt.raiseException("you must return a value");
}
} else {
rt.raiseException("you must return a value");
}
} else {
if (typeof ret === "Array") {
if (ret[0] === "return" && ret[1]) {
rt.raiseException("you cannot return a value of a void function");
if (typeof ret === "Array") {
if (ret[0] === "return" && ret[1]) {
rt.raiseException("you cannot return a value of a void function");
}
}
ret = void 0;
}
ret = void 0;
}
rt.exitScope("function " + name);
return ret;
};
this.regFunc(f, lt, name, argTypes, retType);
rt.exitScope("function " + name);
return ret;
};
this.regFunc(f, lt, name, argTypes, retType);
} else {
this.regFuncPrototype(lt, name, argTypes, retType);
}
};

CRuntime.prototype.makeParametersSigniture = function(args) {
Expand All @@ -156,7 +160,7 @@ CRuntime.prototype.makeParametersSigniture = function(args) {
};

CRuntime.prototype.getCompatibleFunc = function(lt, name, args) {
var argsStr, compatibles, ltsig, rt, sig, t, ts;
var argsStr, compatibles, ltsig, ret, rt, sig, t, ts;
ltsig = this.getTypeSigniture(lt);
if (ltsig in this.types) {
t = this.types[ltsig];
Expand All @@ -166,7 +170,7 @@ CRuntime.prototype.getCompatibleFunc = function(lt, name, args) {
});
sig = this.makeParametersSigniture(ts);
if (sig in t[name]) {
return t[name][sig];
ret = t[name][sig];
} else {
compatibles = [];
rt = this;
Expand All @@ -192,17 +196,18 @@ CRuntime.prototype.getCompatibleFunc = function(lt, name, args) {
});
if (compatibles.length === 0) {
if ("#default" in t[name]) {
return t[name]["#default"];
ret = t[name]["#default"];
} else {
rt = this;
argsStr = ts.map(function(v) {
return rt.makeTypeString(v);
}).join(",");
this.raiseException("no method " + name + " in " + lt + " accepts " + argsStr);
}
rt = this;
argsStr = ts.map(function(v) {
return rt.makeTypeString(v);
}).join(",");
this.raiseException("no method " + name + " in " + lt + " accepts " + argsStr);
} else if (compatibles.length > 1) {
this.raiseException("ambiguous method invoking, " + compatibles.length + " compatible methods");
} else {
return compatibles[0];
ret = compatibles[0];
}
}
} else {
Expand All @@ -211,6 +216,10 @@ CRuntime.prototype.getCompatibleFunc = function(lt, name, args) {
} else {
this.raiseException("type " + this.makeTypeString(lt) + " is unknown");
}
if (ret == null) {
this.raiseException("method " + name + " does not seem to be implemented");
}
return ret;
};

CRuntime.prototype.matchVarArg = function(methods, sig) {
Expand Down Expand Up @@ -291,7 +300,7 @@ CRuntime.prototype.regOperator = function(f, lt, name, args, retType) {
return this.regFunc(f, lt, this.makeOperatorFuncName(name), args, retType);
};

CRuntime.prototype.regFunc = function(f, lt, name, args, retType) {
CRuntime.prototype.regFuncPrototype = function(lt, name, args, retType) {
var ltsig, sig, t, type;
ltsig = this.getTypeSigniture(lt);
if (ltsig in this.types) {
Expand All @@ -308,7 +317,42 @@ CRuntime.prototype.regFunc = function(f, lt, name, args, retType) {
}
type = this.functionPointerType(retType, args);
if (lt === "global") {
this.defVar(name, type, this.val(type, this.makeFunctionPointerValue(f, name, lt, args, retType)));
this.defVar(name, type, this.val(type, this.makeFunctionPointerValue(null, name, lt, args, retType)));
}
t[name][sig] = null;
t[name]["reg"].push(args);
} else {
this.raiseException("type " + this.makeTypeString(lt) + " is unknown");
}
};

CRuntime.prototype.regFunc = function(f, lt, name, args, retType) {
var func, ltsig, sig, t, type;
ltsig = this.getTypeSigniture(lt);
if (ltsig in this.types) {
t = this.types[ltsig];
if (!(name in t)) {
t[name] = {};
}
if (!("reg" in t[name])) {
t[name]["reg"] = [];
}
sig = this.makeParametersSigniture(args);
if (sig in t[name] && (t[name][sig] != null)) {
this.raiseException("method " + name + " with parameters (" + sig + ") is already defined");
}
type = this.functionPointerType(retType, args);
if (lt === "global") {
if (this.varAlreadyDefined(name)) {
func = this.scope[0][name];
if (func.v.target !== null) {
this.raiseException("global method " + name + " with parameters (" + sig + ") is already defined");
} else {
func.v.target = f;
}
} else {
this.defVar(name, type, this.val(type, this.makeFunctionPointerValue(f, name, lt, args, retType)));
}
}
t[name][sig] = f;
t[name]["reg"].push(args);
Expand Down Expand Up @@ -366,24 +410,35 @@ CRuntime.prototype.promoteNumeric = function(l, r) {
};

CRuntime.prototype.readVar = function(varname) {
var i, vc;
var i, ret, vc;
i = this.scope.length - 1;
while (i >= 0) {
vc = this.scope[i];
if (vc[varname]) {
return vc[varname];
ret = vc[varname];
if (this.isFunctionType(ret.t) && ret.v.target === null) {
this.raiseException("function " + ret.v.name + " does not seem to be implemented");
} else {
return ret;
}
}
i--;
}
this.raiseException("variable " + varname + " does not exist");
};

CRuntime.prototype.defVar = function(varname, type, initval) {
CRuntime.prototype.varAlreadyDefined = function(varname) {
var vc;
vc = this.scope[this.scope.length - 1];
if (varname in vc) {
return varname in vc;
};

CRuntime.prototype.defVar = function(varname, type, initval) {
var vc;
if (this.varAlreadyDefined(varname)) {
this.raiseException("variable " + varname + " already defined");
}
vc = this.scope[this.scope.length - 1];
initval = this.clone(this.cast(type, initval));
if (initval === void 0) {
vc[varname] = this.defaultValue(type);
Expand Down
2 changes: 1 addition & 1 deletion pegjs/ast.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ NamespaceAliasDefinition
;

FunctionDefinition
= a:DeclarationSpecifiers b:Declarator c:DeclarationList? d:CompoundStatement {
= a:DeclarationSpecifiers b:Declarator c:DeclarationList? d:(SEMI {return null;} / CompoundStatement) {
return addPositionInfo({type:'FunctionDefinition', DeclarationSpecifiers:a, Declarator:b, DeclarationList:c, CompoundStatement:d});
}
;
Expand Down
Loading

0 comments on commit 26e7630

Please sign in to comment.