Skip to content

Commit

Permalink
new syntax for declaring multi parameter types
Browse files Browse the repository at this point in the history
  • Loading branch information
NotFound committed Jun 1, 2012
1 parent 678cd52 commit 3357c6a
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 8 deletions.
25 changes: 24 additions & 1 deletion t/advanced/10multi.t
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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");
Expand Down
52 changes: 45 additions & 7 deletions winxedst2.winxed
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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()
{
Expand Down Expand Up @@ -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"));
Expand Down Expand Up @@ -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();
}
}
}

Expand Down Expand Up @@ -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; }
Expand Down

0 comments on commit 3357c6a

Please sign in to comment.