diff --git a/pol-core/bscript/compiler.cpp b/pol-core/bscript/compiler.cpp index 9f504075c..0de00f1f5 100644 --- a/pol-core/bscript/compiler.cpp +++ b/pol-core/bscript/compiler.cpp @@ -559,7 +559,7 @@ int Compiler::getStructMembers( Expression& expr, CompilerContext& ctx ) if ( token.id == TOK_IDENT || token.id == TOK_STRING ) { Token ident_tkn; - Parser::getToken( ctx, ident_tkn ); + getTokenWithoutConversions( ctx, ident_tkn ); res = peekToken( ctx, token ); if ( token.id == TOK_ASSIGN ) @@ -825,7 +825,7 @@ int Compiler::getUserArgs( Expression& ex, CompilerContext& ctx, bool inject_jsr CompilerContext tctx( ctx ); - res = getToken( tctx, tk ); + res = getTokenWithoutConversions( tctx, tk ); if ( res < 0 ) return res; if ( tk.id == TOK_RPAREN ) @@ -1747,8 +1747,7 @@ int Compiler::readFunctionDeclaration( CompilerContext& ctx, UserFunction& userf peekToken( ctx, token ); for ( ;; ) { - Token paramName; - res = getToken( ctx, token ); + res = getTokenWithoutConversions( ctx, token ); if ( res ) return -1; @@ -1760,7 +1759,7 @@ int Compiler::readFunctionDeclaration( CompilerContext& ctx, UserFunction& userf if ( token.id == TOK_REFTO ) { pass_by_reference = true; - res = getToken( ctx, token ); + res = getTokenWithoutConversions( ctx, token ); if ( res ) return -1; } diff --git a/pol-core/bscript/parser.cpp b/pol-core/bscript/parser.cpp index 4e9ed379f..c0225b202 100644 --- a/pol-core/bscript/parser.cpp +++ b/pol-core/bscript/parser.cpp @@ -1998,6 +1998,16 @@ int SmartParser::getToken( CompilerContext& ctx, Token& token, Expression* pexpr return res; } +/** + * Get a token, but bypass the conversions in SmartParser::getToken + * Primarily used when getting an identifier that may be the same as + * a userfunc name. + */ +int SmartParser::getTokenWithoutConversions( CompilerContext& ctx, Token& token ) +{ + return Parser::getToken( ctx, token ); +} + bool SmartParser::callingMethod( CompilerContext& ctx ) { // if we have something like x.foo(), change to call-method diff --git a/pol-core/bscript/parser.h b/pol-core/bscript/parser.h index d63b6add8..8ac0c9f14 100644 --- a/pol-core/bscript/parser.h +++ b/pol-core/bscript/parser.h @@ -138,6 +138,7 @@ public: virtual int parseToken( CompilerContext& ctx, Expression& expr, Token* ) override; virtual int getToken( CompilerContext& ctx, Token& token, Expression* expr = nullptr ) override; + int getTokenWithoutConversions( CompilerContext& ctx, Token& token ); bool callingMethod( CompilerContext& ctx ); diff --git a/testsuite/escript/bug/bug011-module-function-param-name-clash.out b/testsuite/escript/bug/bug011-module-function-param-name-clash.out new file mode 100644 index 000000000..4f3e648ea --- /dev/null +++ b/testsuite/escript/bug/bug011-module-function-param-name-clash.out @@ -0,0 +1 @@ +Area is 200 diff --git a/testsuite/escript/bug/bug011-module-function-param-name-clash.src b/testsuite/escript/bug/bug011-module-function-param-name-clash.src new file mode 100644 index 000000000..fa3923fe4 --- /dev/null +++ b/testsuite/escript/bug/bug011-module-function-param-name-clash.src @@ -0,0 +1,20 @@ +// There was a bug where module function parameter name tokens would be +// converted to be userfunction names, if there was a userfunction +// with the same name as the parameter. +// +// In this test, the storage.em module has a few methods with +// a parameter named "area", but we should still be able to +// define a function named "area" too. +// +use storage; + +program display_area() + var h := 10; + var w := 20; + print("Area is " +CStr(area(h, w))); +endprogram + +function area(ht, wd) + return ht * wd; +endfunction + diff --git a/testsuite/escript/bug/bug012-function-as-named-parameter.out b/testsuite/escript/bug/bug012-function-as-named-parameter.out new file mode 100644 index 000000000..0504e4795 --- /dev/null +++ b/testsuite/escript/bug/bug012-function-as-named-parameter.out @@ -0,0 +1 @@ +the argument value is as expected diff --git a/testsuite/escript/bug/bug012-function-as-named-parameter.src b/testsuite/escript/bug/bug012-function-as-named-parameter.src new file mode 100644 index 000000000..a11317a19 --- /dev/null +++ b/testsuite/escript/bug/bug012-function-as-named-parameter.src @@ -0,0 +1,17 @@ +// There was a bug where module function parameter name tokens would be +// converted to be userfunction names, if there was a userfunction +// with the same name as the parameter. +// +// In this test, "print" in the basicio module names +// its parameter "anything", but we should still +// be able to use that name for a function, +// and still pass the argument by name. +// +function anything( s ) + return "the argument value is " + s; +endfunction + +program print_anything() + var s := anything("as expected"); + print( anything := s ); +endprogram