diff --git a/modcc/parser.cpp b/modcc/parser.cpp index 86ae2accd4984c311ebdc5b58d8c5a75c52a4711..e54c9830940ba1828e8dd2e1a9b1ecd868ad9f0b 100644 --- a/modcc/parser.cpp +++ b/modcc/parser.cpp @@ -973,6 +973,14 @@ symbol_ptr Parser::parse_function() { auto p = parse_prototype(); if (p == nullptr) return nullptr; + // Functions may have a unit attached + if (token_.type == tok::lparen) { + unit_description(); + if (status_ == lexerStatus::error) { + return {}; + } + } + // check for opening left brace { if (!expect(tok::lbrace)) return nullptr; diff --git a/test/unit-modcc/test_parser.cpp b/test/unit-modcc/test_parser.cpp index 3af61a32f0df8f634ef5196f974593361a38c4fa..ba8cc363b0fa8f7dfca67f59f8ca55e423928512 100644 --- a/test/unit-modcc/test_parser.cpp +++ b/test/unit-modcc/test_parser.cpp @@ -205,17 +205,46 @@ TEST(Parser, net_receive) { } TEST(Parser, function) { - char str[] = - "FUNCTION foo(x, y) {" - " LOCAL a\n" - " a = 3\n" - " b = x * y + 2\n" - " y = x + y * 2\n" - " foo = a * x + y\n" - "}"; + { + char str[] = + "FUNCTION foo(x, y) {" + " LOCAL a\n" + " a = 3\n" + " b = x * y + 2\n" + " y = x + y * 2\n" + " foo = a * x + y\n" + "}"; + + std::unique_ptr<Symbol> sym; + EXPECT_TRUE(check_parse(sym, &Parser::parse_function, str)); + } + { + char str[] = + "FUNCTION foo(x (mv), y (/mA)) {" + " foo = x * y\n" + "}"; - std::unique_ptr<Symbol> sym; - EXPECT_TRUE(check_parse(sym, &Parser::parse_function, str)); + std::unique_ptr<Symbol> sym; + EXPECT_TRUE(check_parse(sym, &Parser::parse_function, str)); + } + { + char str[] = + "FUNCTION foo(x (mv), y (/mA)) (mv/mA) {" + " foo = x * y\n" + "}"; + + std::unique_ptr<Symbol> sym; + EXPECT_TRUE(check_parse(sym, &Parser::parse_function, str)); + } + { + char str[] = + "FUNCTION foo(x (mv), y (/mA)) (mv-mA) {" + " foo = x * y\n" + "}"; + + std::unique_ptr<Symbol> sym; + EXPECT_FALSE(check_parse(sym, &Parser::parse_function, str)); + } } TEST(Parser, parse_solve) {