Permalink
Browse files

new syntax for declaring multi parameter types

  • Loading branch information...
NotFound committed Jun 1, 2012
1 parent 678cd52 commit 3357c6a75095ee7030843c570ecd5ec45d526d11
Showing with 69 additions and 8 deletions.
  1. +24 −1 t/advanced/10multi.t
  2. +45 −7 winxedst2.winxed
View
@@ -2,13 +2,21 @@
// multi syntax
-using extern Test.More is, done_testing;
+using extern Test.More ok, is, done_testing;
+
+// Implicit multi
function bar(var a) { return "p"; }
function bar(int a, int b) { return "ii"; }
function bar(int a) { return "i"; }
function bar(string a, string b) { return "ss"; }
+// Explicit multi with ':' syntax in parameter
+
+function qbar(:string s) { return s + "there"; }
+
+function qmbar(:FooBar.Foo foo) { return ":FooBar.Foo"; }
+
namespace FooBar
{
@@ -116,6 +124,21 @@ function main[main]()
is(bar("a", "b"), "ss", "multi(string, string)");
is(bar(3.14), "p", "multi(var)");
+ // These functions have only one definition.
+ // Verify that they accept only the required type.
+ is(qbar("hi"), "hithere", ":string - called");
+ int failed = false;
+ try
+ qbar(0);
+ catch() { failed = true; }
+ ok(failed, ": with string - fails with int");
+ is(qmbar(new FooBar.Foo), ":FooBar.Foo", ": FooBar.Foo - called");
+ failed = false;
+ try
+ qmbar(var(0));
+ catch() { failed = true; }
+ ok(failed, ": with class - fails with Integer");
+
is(FooBar.foo("a"), "FooBar.s-a", "multi(string) in reopened namespace");
is(FooBar.foo(42), "FooBar.i-42", "multi(int) in reopened namespace");
View
@@ -10598,18 +10598,33 @@ class FunctionParameter
var name;
var modifiers;
var type;
+ var want_multi;
+ var classtype;
var defaultexpr;
function FunctionParameter(var func, var tk)
{
// Syntax: [type] name [modifiers] [ = default]
self.func = func;
var t = tk.get();
- string type = typetoregcheck(t.checkkeyword());
- if (type != "")
+ string type;
+ if (t.isop(":")) {
+ self.want_multi = true;
t = tk.get();
- else
- type = REGvar;
+ type = typetoregcheck(t.checkkeyword());
+ if (type == "") {
+ type = REGvar;
+ self.classtype = new ClassSpecifierId(tk, func.owner, t);
+ }
+ t = tk.get();
+ }
+ else {
+ type = typetoregcheck(t.checkkeyword());
+ if (type != "")
+ t = tk.get();
+ else
+ type = REGvar;
+ }
self.type = type;
self.name = t;
@@ -10676,9 +10691,19 @@ class FunctionParameter
{
return self.type;
}
+ function wantMulti()
+ {
+ return self.want_multi != null;
+ }
function get_pir_multi_type()
{
- return typetopirname(self.type);
+ var classtype = self.classtype;
+ if (classtype == null)
+ return typetopirname(self.type);
+ var clkey = classtype.checknskey(self.func.owner);
+ if (clkey == null)
+ SyntaxError("class not found", classtype);
+ return clkey.getparrotkey();
}
function getvar()
{
@@ -10777,6 +10802,13 @@ class FunctionParameterList
{
for_each(self.paramlist, bindlast(bindmethod("emitdefault"), e));
}
+ function wantMulti()
+ {
+ for (var param in self.paramlist)
+ if (param.wantMulti())
+ return true;
+ return false;
+ }
function addmultisig(var multi_sig)
{
transform(self.paramlist, multi_sig, bindmethod("get_pir_multi_type"));
@@ -10949,7 +10981,13 @@ class FunctionBase : BlockStatement
var t = tk.get();
if (! t.isop(")")) {
tk.unget(t);
- self.params = new FunctionParameterList(tk, self);
+ var params = new FunctionParameterList(tk, self);
+ self.params = params;
+ if (params.wantMulti()) {
+ if (! (self instanceof FunctionStatement))
+ SyntaxError("Can't use multi signatures here", self);
+ self.setmulti();
+ }
}
}
@@ -11181,8 +11219,8 @@ class FunctionStatement : FunctionBase
self.FunctionBase(start, owner);
self.paramnum = 0;
self.lexnum = 0;
- self.parse(tk);
self.is_multi = new ["Boolean"];
+ self.parse(tk);
}
function isanonymous() { return false; }

0 comments on commit 3357c6a

Please sign in to comment.