From d7df81b9ae8b6074aa281d9412cbdaf93a84be87 Mon Sep 17 00:00:00 2001 From: Nicolas Cannasse Date: Thu, 11 Sep 2014 18:13:38 +0200 Subject: [PATCH] added optional parameters support --- hscript/Expr.hx | 4 +++- hscript/Interp.hx | 28 +++++++++++++++++++++++++++- hscript/Parser.hx | 21 ++++++++++++++------- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/hscript/Expr.hx b/hscript/Expr.hx index ed31aea..1bab2c7 100644 --- a/hscript/Expr.hx +++ b/hscript/Expr.hx @@ -57,7 +57,7 @@ enum Expr { EFor( v : String, it : Expr, e : Expr ); EBreak; EContinue; - EFunction( args : Array<{ name : String, t : Null }>, e : Expr, ?name : String, ?ret : CType ); + EFunction( args : Array, e : Expr, ?name : String, ?ret : CType ); EReturn( ?e : Expr ); EArray( e : Expr, index : Expr ); EArrayDecl( e : Array ); @@ -69,6 +69,8 @@ enum Expr { ESwitch( e : Expr, cases : Array<{ values : Array, expr : Expr }>, ?defaultExpr : Expr); } +typedef Argument = { name : String, ?t : CType, ?opt : Bool }; + enum CType { CTPath( path : Array, ?params : Array ); CTFun( args : Array, ret : CType ); diff --git a/hscript/Interp.hx b/hscript/Interp.hx index efaf654..d14f12d 100644 --- a/hscript/Interp.hx +++ b/hscript/Interp.hx @@ -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) { - 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 ) diff --git a/hscript/Parser.hx b/hscript/Parser.hx index 1cb6472..4eade93 100644 --- a/hscript/Parser.hx +++ b/hscript/Parser.hx @@ -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); }