added optional parameters support

This commit is contained in:
Nicolas Cannasse
2014-09-11 18:13:38 +02:00
parent 9368695d03
commit d7df81b9ae
3 changed files with 44 additions and 9 deletions
+3 -1
View File
@@ -57,7 +57,7 @@ enum Expr {
EFor( v : String, it : Expr, e : Expr );
EBreak;
EContinue;
EFunction( args : Array<{ name : String, t : Null<CType> }>, e : Expr, ?name : String, ?ret : CType );
EFunction( args : Array<Argument>, e : Expr, ?name : String, ?ret : CType );
EReturn( ?e : Expr );
EArray( e : Expr, index : Expr );
EArrayDecl( e : Array<Expr> );
@@ -69,6 +69,8 @@ enum Expr {
ESwitch( e : Expr, cases : Array<{ values : Array<Expr>, expr : Expr }>, ?defaultExpr : Expr);
}
typedef Argument = { name : String, ?t : CType, ?opt : Bool };
enum CType {
CTPath( path : Array<String>, ?params : Array<CType> );
CTFun( args : Array<CType>, ret : CType );
+27 -1
View File
@@ -345,8 +345,34 @@ class Interp {
case EFunction(params,fexpr,name,_):
var capturedLocals = duplicate(locals);
var me = this;
var hasOpt = false, minParams = 0;
for( p in params )
if( p.opt )
hasOpt = true;
else
minParams++;
var f = function(args:Array<Dynamic>) {
if( args.length != params.length ) throw "Invalid number of parameters";
if( args.length != params.length ) {
if( args.length < minParams ) {
var str = "Invalid number of parameters. Got " + args.length + ", required " + minParams;
if( name != null ) str += " for function '" + name+"'";
throw str;
}
// make sure mandatory args are forced
var args2 = [];
var extraParams = args.length - minParams;
var pos = 0;
for( p in params )
if( p.opt ) {
if( extraParams > 0 ) {
args2.push(args[pos++]);
extraParams--;
} else
args2.push(null);
} else
args2.push(args[pos++]);
args = args2;
}
var old = me.locals;
me.locals = me.duplicate(capturedLocals);
for( i in 0...params.length )
+14 -7
View File
@@ -469,25 +469,32 @@ class Parser {
var args = new Array();
tk = token();
if( tk != TPClose ) {
var arg = true;
while( arg ) {
var name = null;
var done = false;
while( !done ) {
var name = null, opt = false;
switch( tk ) {
case TQuestion:
opt = true;
tk = token();
default:
}
switch( tk ) {
case TId(id): name = id;
default: unexpected(tk);
}
tk = token();
var t = null;
var arg : Argument = { name : name };
args.push(arg);
if( opt ) arg.opt = true;
if( tk == TDoubleDot && allowTypes ) {
t = parseType();
arg.t = parseType();
tk = token();
}
args.push( { name : name, t : t } );
switch( tk ) {
case TComma:
tk = token();
case TPClose:
arg = false;
done = true;
default:
unexpected(tk);
}