* Implement `...' and default function arguments.
This commit is contained in:
		
							parent
							
								
									8a10360c91
								
							
						
					
					
						commit
						ef8bd919fc
					
				
					 1 changed files with 31 additions and 7 deletions
				
			
		|  | @ -215,20 +215,40 @@ static void eval(Env * env, Expr e, Value & v) | ||||||
|             eval(env, arg, *vArg); |             eval(env, arg, *vArg); | ||||||
|             if (vArg->type != tAttrs) throw TypeError("expected attribute set"); |             if (vArg->type != tAttrs) throw TypeError("expected attribute set"); | ||||||
|              |              | ||||||
|  |             /* For each formal argument, get the actual argument.  If
 | ||||||
|  |                there is no matching actual argument but the formal | ||||||
|  |                argument has a default, use the default. */ | ||||||
|  |             unsigned int attrsUsed = 0; | ||||||
|             for (ATermIterator i(formals); i; ++i) { |             for (ATermIterator i(formals); i; ++i) { | ||||||
|                 Expr name, def; |                 Expr name, def; | ||||||
|                 DefaultValue def2; |                 DefaultValue def2; | ||||||
|                 if (!matchFormal(*i, name, def2)) abort(); /* can't happen */ |                 if (!matchFormal(*i, name, def2)) abort(); /* can't happen */ | ||||||
| 
 | 
 | ||||||
|                 Bindings::iterator j = vArg->attrs->find(aterm2String(name)); |                 Bindings::iterator j = vArg->attrs->find(aterm2String(name)); | ||||||
|                 if (j == vArg->attrs->end()) |  | ||||||
|                     throw TypeError(format("the argument named `%1%' required by the function is missing") |  | ||||||
|                     % aterm2String(name)); |  | ||||||
|                  |                  | ||||||
|                 Value & v = env2->bindings[aterm2String(name)]; |                 Value & v = env2->bindings[aterm2String(name)]; | ||||||
|  |                  | ||||||
|  |                 if (j == vArg->attrs->end()) { | ||||||
|  |                     if (!matchDefaultValue(def2, def)) def = 0; | ||||||
|  |                     if (def == 0) throw TypeError(format("the argument named `%1%' required by the function is missing") | ||||||
|  |                         % aterm2String(name)); | ||||||
|  |                     v.type = tThunk; | ||||||
|  |                     v.thunk.env = env2; | ||||||
|  |                     v.thunk.expr = def; | ||||||
|  |                 } else { | ||||||
|  |                     attrsUsed++; | ||||||
|                     v.type = tCopy; |                     v.type = tCopy; | ||||||
|                     v.val = &j->second; |                     v.val = &j->second; | ||||||
|                 } |                 } | ||||||
|  |              | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /* Check that each actual argument is listed as a formal
 | ||||||
|  |                argument (unless the attribute match specifies a | ||||||
|  |                `...').  TODO: show the names of the | ||||||
|  |                expected/unexpected arguments. */ | ||||||
|  |             if (ellipsis == eFalse && attrsUsed != vArg->attrs->size()) | ||||||
|  |                 throw TypeError("function called with unexpected argument"); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         else abort(); |         else abort(); | ||||||
|  | @ -266,6 +286,10 @@ void run(Strings args) | ||||||
|     doTest("({x, y}: x) { x = 1; y = 2; }"); |     doTest("({x, y}: x) { x = 1; y = 2; }"); | ||||||
|     doTest("({x, y}@args: args.x) { x = 1; y = 2; }"); |     doTest("({x, y}@args: args.x) { x = 1; y = 2; }"); | ||||||
|     doTest("(args@{x, y}: args.x) { x = 1; y = 2; }"); |     doTest("(args@{x, y}: args.x) { x = 1; y = 2; }"); | ||||||
|  |     doTest("({x ? 1}: x) { }"); | ||||||
|  |     doTest("({x ? 1, y ? x}: y) { x = 2; }"); | ||||||
|  |     doTest("({x, y, ...}: x) { x = 1; y = 2; z = 3; }"); | ||||||
|  |     doTest("({x, y, ...}@args: args.z) { x = 1; y = 2; z = 3; }"); | ||||||
|      |      | ||||||
|     //Expr e = parseExprFromString(state, "let x = \"a\"; in x + \"b\"", "/");
 |     //Expr e = parseExprFromString(state, "let x = \"a\"; in x + \"b\"", "/");
 | ||||||
|     //Expr e = parseExprFromString(state, "(x: x + \"b\") \"a\"", "/");
 |     //Expr e = parseExprFromString(state, "(x: x + \"b\") \"a\"", "/");
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue