Skip to content

Commit

Permalink
#341 add overloading test cases / fixing bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Sep 24, 2015
1 parent 498167a commit 5a5d98e
Show file tree
Hide file tree
Showing 8 changed files with 373 additions and 31 deletions.
14 changes: 9 additions & 5 deletions packages/corto/ast/src/ast_Parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1300,7 +1300,6 @@ ast_Storage _ast_Parser_declareFunction(ast_Parser this, cx_type returnType, cx_
/* $begin(::corto::ast::Parser::declareFunction) */
cx_function function;
cx_object o;
cx_type functionType = cx_type(kind);
ast_Storage result = NULL;
cx_int32 distance;
ast_CHECK_ERRSET(this);
Expand Down Expand Up @@ -1335,11 +1334,11 @@ ast_Storage _ast_Parser_declareFunction(ast_Parser this, cx_type returnType, cx_
/* This could be an implementation after a forward declaration so try to resolve
* function first. */
if (!((function = cx_lookupFunction(this->scope, id, &distance)) && !distance)) {
if (!functionType) {
if (!kind) {
if (cx_class_instanceof(cx_interface_o, this->scope)) {
functionType = cx_type(cx_method_o);
kind = cx_type(cx_method_o);
} else {
functionType = cx_type(cx_function_o);
kind = cx_type(cx_function_o);
}
} else {
/* Check whether declaration is a delegate */
Expand All @@ -1359,7 +1358,7 @@ ast_Storage _ast_Parser_declareFunction(ast_Parser this, cx_type returnType, cx_
goto error;
}

function = cx_declareChild(this->scope, id, functionType);
function = cx_declareChild(this->scope, id, kind);
if (!function) {
ast_Parser_error(this, "declare of '%s' failed",
functionName);
Expand All @@ -1370,6 +1369,11 @@ ast_Storage _ast_Parser_declareFunction(ast_Parser this, cx_type returnType, cx_
function->returnsReference = returnsReference;
}
} else {
if (strcmp(id, cx_nameof(function))) {
ast_Parser_error(this, "overloaded function '%s' conflicts with '%s'",
id, cx_nameof(function));
goto error;
}
cx_release(function);
}

Expand Down
25 changes: 14 additions & 11 deletions packages/corto/lang/src/cx_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -3126,7 +3126,9 @@ static cx_uint32 cx_overloadParamCompare(
goto nomatch; /* Parameter accepts only references */
} else {
if (!r_forceReference) {
d++; /* Favor pass by value in case of implicit reference passing */
if (!r_null) {
d++; /* Favor pass by value in case of implicit reference passing */
}
}
}
} else if (r_reference) {
Expand Down Expand Up @@ -3360,6 +3362,7 @@ typedef struct cx_lookupFunction_t {
cx_function result;
cx_bool error;
cx_int32 d;
cx_int32 old_d;
}cx_lookupFunction_t;

/* Lookup function in scope */
Expand All @@ -3379,23 +3382,17 @@ int cx_lookupFunctionWalk(cx_object o, void* userData) {
goto found;
}
} else {
cx_id name;
cx_signatureName(cx_nameof(o), name); /* Obtain function name */
if (!stricmp(name, data->request)) {
d = INT_MAX-1;
}
cx_assert(0, "cx_lookupFunction only handles requests with parentheses");
}

if (d != -1) {
if (d <= data->d) {
data->old_d = data->d;
}
if (d < data->d) {
data->result = o;
data->d = d;
}

/* If distance is zero, the function is an exact match. */
if (!d) {
goto found;
}
}
}

Expand Down Expand Up @@ -3447,13 +3444,19 @@ cx_function cx_lookupFunction(cx_object scope, cx_string requested, cx_int32* d)
walkData.result = NULL;
walkData.error = FALSE;
walkData.d = INT_MAX;
walkData.old_d = INT_MAX;

for (i = 0; i < scopeContents.length; i++) {
if (!cx_lookupFunctionWalk(scopeContents.buffer[i], &walkData)) {
break;
}
}

if (walkData.d != INT_MAX && (walkData.d == walkData.old_d)) {
cx_seterr("ambiguous reference '%s'", walkData.request);
walkData.error = TRUE;
}

if (walkData.error) {
return NULL;
}
Expand Down
11 changes: 11 additions & 0 deletions packages/corto/lang/src/cx_resolver.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,15 @@ cx_object cx_resolve(cx_object _scope, cx_string str) {
cx_release(lookup); /* Free reference */
}
lookup = o;
if (o) {
if (cx_instanceof(cx_function_o, o)) {
if (cx_function(o)->overloaded == TRUE) {
cx_release(o);
cx_seterr("ambiguous reference to '%s'", str);
goto error;
}
}
}

if (!o) {
if (!i && (prev != corto_lang_o) && cx_instanceof(cx_type(cx_package_o), prev)) {
Expand Down Expand Up @@ -232,4 +241,6 @@ cx_object cx_resolve(cx_object _scope, cx_string str) {
}

return o;
error:
return NULL;
}
81 changes: 81 additions & 0 deletions packages/corto/lang/test/src/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,87 @@ cx_void _test_functionToResolve(cx_int32 a, cx_int32 b) {
/* $end */
}

/* ::test::ol_int(int32 a) */
cx_void _test_ol_int(cx_int32 a) {
/* $begin(::test::ol_int) */

/* << Insert implementation >> */

/* $end */
}

/* ::test::ol_null(bool a) */
cx_void _test_ol_null_bool(cx_bool a) {
/* $begin(::test::ol_null(bool a)) */

/* << Insert implementation >> */

/* $end */
}

/* ::test::ol_null(object a) */
cx_void _test_ol_null_object(cx_object a) {
/* $begin(::test::ol_null(object a)) */

/* << Insert implementation >> */

/* $end */
}

/* ::test::ol_null(string a) */
cx_void _test_ol_null_string(cx_string a) {
/* $begin(::test::ol_null(string a)) */

/* << Insert implementation >> */

/* $end */
}

/* ::test::ol_num(float64 a) */
cx_void _test_ol_num_float64(cx_float64 a) {
/* $begin(::test::ol_num(float64 a)) */

/* << Insert implementation >> */

/* $end */
}

/* ::test::ol_num(int32 a) */
cx_void _test_ol_num_int32(cx_int32 a) {
/* $begin(::test::ol_num(int32 a)) */

/* << Insert implementation >> */

/* $end */
}

/* ::test::ol_uint(int32 a) */
cx_void _test_ol_uint(cx_int32 a) {
/* $begin(::test::ol_uint) */

/* << Insert implementation >> */

/* $end */
}

/* ::test::ol_wildcard(float32 a,string b) */
cx_void _test_ol_wildcard_float32_string(cx_float32 a, cx_string b) {
/* $begin(::test::ol_wildcard(float32 a,string b)) */

/* << Insert implementation >> */

/* $end */
}

/* ::test::ol_wildcard(int32 a,string b) */
cx_void _test_ol_wildcard_int32_string(cx_int32 a, cx_string b) {
/* $begin(::test::ol_wildcard(int32 a,string b)) */

/* << Insert implementation >> */

/* $end */
}

int testMain(int argc, char* argv[]) {
/* $begin(main) */
int result = 0;
Expand Down
Loading

0 comments on commit 5a5d98e

Please sign in to comment.