Esempio n. 1
0
 def test_precedence(self):
     buf = """
     fn prec() -> int {
       2 + 3 * 2 + 2 / 8;
     }
     """
     exprs = [
         ast.Function(
             "prec",
             [],
             [
                 ast.ExprStatement(
                     ast.BinaryOp(
                         ast.BinaryOp(
                             ast.Number(2),
                             ast.BinaryOp(ast.Number(3), ast.Number(2),
                                          Token(TokenType.MULTIPLY, "*")),
                             Token(TokenType.ADD, "+"),
                         ),
                         ast.BinaryOp(ast.Number(2), ast.Number(8),
                                      Token(TokenType.DIVIDE, "/")),
                         Token(TokenType.ADD, "+"),
                     ))
             ],
             ast.Type(ast.TypeKind.INT),
         )
     ]
     self._test_parse_impl(buf, exprs)
Esempio n. 2
0
 def test_constructor(self):
     buf = """
     fn constructorTest() -> int {
       let foo = new Foo(name, age);
       return 0;
     }
     """
     exprs = [
         ast.Function(
             "constructorTest",
             [],
             [
                 ast.LetStatement(
                     "foo",
                     ast.Constructor(
                         "Foo",
                         [ast.VariableRef("name"),
                          ast.VariableRef("age")]),
                 ),
                 ast.ReturnStatement(ast.Number(0)),
             ],
             ast.Type(ast.TypeKind.INT),
         )
     ]
     self._test_parse_impl(buf, exprs)
Esempio n. 3
0
 def test_struct_with_member_functions(self):
     buf = """
     struct Foo {
       string name;
       int age;
       fn memberFunc() -> int {
         return age;
       }
     };
     """
     exprs = [
         ast.Structure(
             "Foo",
             [
                 ast.Member("name", ast.Type(ast.TypeKind.STRING)),
                 ast.Member("age", ast.Type(ast.TypeKind.INT)),
             ],
             [
                 ast.Function(
                     "memberFunc",
                     [("this", ast.Type(ast.TypeKind.USER, "Foo"))],
                     [ast.ReturnStatement(ast.VariableRef("age"))],
                     ast.Type(ast.TypeKind.INT),
                 )
             ],
         )
     ]
     self._test_parse_impl(buf, exprs)
Esempio n. 4
0
 def test_while_loop(self):
     buf = """
     fn loopTest(int x) -> int {
       while (x < 5) {
         print("blah");
       }
       return 0;
     }
     """
     exprs = [
         ast.Function(
             "loopTest",
             [("x", ast.Type(ast.TypeKind.INT))],
             [
                 ast.WhileLoop(
                     ast.BinaryOp(ast.VariableRef("x"), ast.Number(5),
                                  Token(TokenType.LESS_THAN, "<")),
                     [
                         ast.ExprStatement(
                             ast.FunctionCall("print",
                                              [ast.String("blah")]))
                     ],
                 ),
                 ast.ReturnStatement(ast.Number(0)),
             ],
             ast.Type(ast.TypeKind.INT),
         )
     ]
     self._test_parse_impl(buf, exprs)
Esempio n. 5
0
 def test_if_statements(self):
     buf = """
     fn foo() -> string {
       if (3 == 3) {
         return "foo";
       }
       return "bar";
     }
     """
     exprs = [
         ast.Function(
             "foo",
             [],
             [
                 ast.IfStatement(
                     ast.BinaryOp(ast.Number(3), ast.Number(3),
                                  Token(TokenType.EQUALS, "==")),
                     [ast.ReturnStatement(ast.String("foo"))],
                     list(),
                 ),
                 ast.ReturnStatement(ast.String("bar")),
             ],
             ast.Type(ast.TypeKind.STRING),
         )
     ]
     self._test_parse_impl(buf, exprs)
Esempio n. 6
0
    def _parse_function(self, this=None):
        f_name = self.cur_tok.value
        self._expect_token(TokenType.IDENTIFIER)
        self._expect_token(TokenType.L_BRACKET)

        # Parse function arguments.
        args = list()
        while not self._consume_token(TokenType.R_BRACKET):
            if args:
                self._expect_token(TokenType.COMMA)
            arg_type = self._parse_type()
            arg_name = self.cur_tok.value
            self._expect_token(TokenType.IDENTIFIER)
            args.append((arg_name, arg_type))

        # Parse return type.
        self._expect_token(TokenType.ARROW)
        return_type = self._parse_type()

        self._expect_token(TokenType.L_BRACE)
        statements = list()
        while not self._consume_token(TokenType.R_BRACE):
            statements.append(self._parse_statement())

        if this is not None:
            args.insert(0, this)

        return ast.Function(f_name, args, statements, return_type)
Esempio n. 7
0
 def _do_FunctionDefinition(self, node):
     decorators = self.transform_decorator(node.Decorators)
     name = str(node.Name)
     argnames, defaults, flags = self.function_info(node)
     doc = node.Documentation
     code = self.transform_suite(node.Body)
     if doc:
         del code.nodes[0]
     return ast.Function(decorators, name, argnames, defaults, flags, doc,
                         code)
Esempio n. 8
0
 def test_string_literals(self):
     buf = """
     fn fooString() -> string {
       return "string_literal_value";
     }
     """
     exprs = [
         ast.Function(
             "fooString",
             [],
             [ast.ReturnStatement(ast.String("string_literal_value"))],
             ast.Type(ast.TypeKind.STRING),
         )
     ]
     self._test_parse_impl(buf, exprs)
Esempio n. 9
0
 def test_function_call(self):
     buf = """
     fn funcCall() -> int {
       return otherFunc();
     }
     """
     exprs = [
         ast.Function(
             "funcCall",
             [],
             [ast.ReturnStatement(ast.FunctionCall("otherFunc", []))],
             ast.Type(ast.TypeKind.INT),
         )
     ]
     self._test_parse_impl(buf, exprs)
Esempio n. 10
0
 def test_function(self):
     buf = """
     fn fooFunc(string name, int age) -> int {
       return 1;
     }
     """
     exprs = [
         ast.Function(
             "fooFunc",
             [("name", ast.Type(ast.TypeKind.STRING)),
              ("age", ast.Type(ast.TypeKind.INT))],
             [ast.ReturnStatement(ast.Number(1))],
             ast.Type(ast.TypeKind.INT),
         )
     ]
     self._test_parse_impl(buf, exprs)
Esempio n. 11
0
 def test_member_access(self):
     buf = """
     fn foo() -> int {
       return bar.age;
     }
     """
     exprs = [
         ast.Function(
             "foo",
             [],
             [
                 ast.ReturnStatement(
                     ast.MemberAccess(ast.VariableRef("bar"), "age"))
             ],
             ast.Type(ast.TypeKind.INT),
         )
     ]
     self._test_parse_impl(buf, exprs)
Esempio n. 12
0
 def test_let_statement(self):
     buf = """
     fn letFunc() -> int {
       let x = 1;
       return x;
     }
     """
     exprs = [
         ast.Function(
             "letFunc",
             [],
             [
                 ast.LetStatement("x", ast.Number(1)),
                 ast.ReturnStatement(ast.VariableRef("x"))
             ],
             ast.Type(ast.TypeKind.INT),
         )
     ]
     self._test_parse_impl(buf, exprs)
Esempio n. 13
0
def test_simple_expression():
    source = """
        export function Main(): void {
            let a = 1 + 2 * 3;
        }
     """
    result = get_semantic_analysis(source)

    assert_equal_programs(
        result,
        ast.Program(
            imports=[],
            traits=[],
            data_defs=[],
            functions=[
                ast.Function(
                    name="Main",
                    is_exported=True,
                    params=[],
                    type=types.Function(name="Main",
                                        params=[],
                                        result=types.Void()),
                    body=[
                        ast.Let(
                            name="a",
                            value=ast.BinaryOperation(
                                operator=ast.BinaryOperator.ADD,
                                left=ast.Number(value=1),
                                right=ast.BinaryOperation(
                                    operator=ast.BinaryOperator.MULTIPLY,
                                    left=ast.Number(value=2),
                                    right=ast.Number(value=3),
                                ),
                            ),
                        )
                    ],
                )
            ],
        ),
    )
Esempio n. 14
0
def p_funcdef(p):
    "funcdef : DEF NAME parameters COLON suite"
    p[0] = ast.Function(None, p[2], tuple(p[3]), (), 0, None, p[5])
Esempio n. 15
0
def test_simple_predicates():
    source = """
        function isGreaterThan(left: i32, right: i32): boolean {
            left > right;
        }

        function isLessThan(left: i32, right: i32): boolean {
            left < right;
        }

        function and(left: boolean, right: boolean): boolean {
            left && right;
        }

        function or(left: boolean, right: boolean): boolean {
            left || right;
        }
     """
    result = get_semantic_analysis(source)

    assert_equal_programs(
        result,
        ast.Program(
            imports=[],
            traits=[],
            data_defs=[],
            functions=[
                ast.Function(
                    name="isGreaterThan",
                    is_exported=False,
                    params=[
                        ast.Param(name="left",
                                  type=types.Param(name="left",
                                                   type=types.I32())),
                        ast.Param(
                            name="right",
                            type=types.Param(name="right", type=types.I32()),
                        ),
                    ],
                    type=types.Function(
                        name="isGreaterThan",
                        params=[
                            types.Param(name="left", type=types.I32()),
                            types.Param(name="right", type=types.I32()),
                        ],
                        result=types.Boolean(),
                    ),
                    body=[
                        ast.BinaryOperation(
                            operator=ast.BinaryOperator.GREATER_THAN,
                            left=ast.Variable(name="left"),
                            right=ast.Variable(name="right"),
                        )
                    ],
                ),
                ast.Function(
                    name="isLessThan",
                    is_exported=False,
                    params=[
                        ast.Param(name="left",
                                  type=types.Param(name="left",
                                                   type=types.I32())),
                        ast.Param(
                            name="right",
                            type=types.Param(name="right", type=types.I32()),
                        ),
                    ],
                    type=types.Function(
                        name="isLessThan",
                        params=[
                            types.Param(name="left", type=types.I32()),
                            types.Param(name="right", type=types.I32()),
                        ],
                        result=types.Boolean(),
                    ),
                    body=[
                        ast.BinaryOperation(
                            operator=ast.BinaryOperator.LESS_THAN,
                            left=ast.Variable(name="left"),
                            right=ast.Variable(name="right"),
                        )
                    ],
                ),
                ast.Function(
                    name="and",
                    is_exported=False,
                    params=[
                        ast.Param(
                            name="left",
                            type=types.Param(name="left",
                                             type=types.Boolean()),
                        ),
                        ast.Param(
                            name="right",
                            type=types.Param(name="right",
                                             type=types.Boolean()),
                        ),
                    ],
                    type=types.Function(
                        name="and",
                        params=[
                            types.Param(name="left", type=types.Boolean()),
                            types.Param(name="right", type=types.Boolean()),
                        ],
                        result=types.Boolean(),
                    ),
                    body=[
                        ast.BinaryOperation(
                            operator=ast.BinaryOperator.AND,
                            left=ast.Variable(name="left"),
                            right=ast.Variable(name="right"),
                        )
                    ],
                ),
                ast.Function(
                    name="or",
                    is_exported=False,
                    params=[
                        ast.Param(
                            name="left",
                            type=types.Param(name="left",
                                             type=types.Boolean()),
                        ),
                        ast.Param(
                            name="right",
                            type=types.Param(name="right",
                                             type=types.Boolean()),
                        ),
                    ],
                    type=types.Function(
                        name="or",
                        params=[
                            types.Param(name="left", type=types.Boolean()),
                            types.Param(name="right", type=types.Boolean()),
                        ],
                        result=types.Boolean(),
                    ),
                    body=[
                        ast.BinaryOperation(
                            operator=ast.BinaryOperator.OR,
                            left=ast.Variable(name="left"),
                            right=ast.Variable(name="right"),
                        )
                    ],
                ),
            ],
        ),
    )
Esempio n. 16
0
def test_trait_with_multiple_implementations():
    source = """
        trait List {
            function length(self: List): i32;
            function sum(self: List): i32;
        }

        data EmptyList() implements List {
            function length(self: List): i32 {
                0;
            }

            function sum(self: List): i32 {
                0;
            }
        }

        data Cons(head: i32, tail: List) implements List {
            function length(self: List): i32 {
                1 + self.tail.length();
            }

            function sum(self: List): i32 {
                self.head + self.tail.sum();
            }
        }
     """
    result = get_semantic_analysis(source)

    assert_equal_programs(
        result,
        ast.Program(
            imports=[],
            traits=[
                ast.Trait(
                    name="List",
                    is_exported=False,
                    functions=[
                        ast.Function(
                            name="length",
                            is_exported=False,
                            params=[
                                ast.Param(
                                    name="self",
                                    type=types.Param(
                                        name="self",
                                        type=types.TypeRef(name="List")),
                                )
                            ],
                            type=types.Function(
                                name="length",
                                params=[
                                    types.Param(
                                        name="self",
                                        type=types.TypeRef(name="List"))
                                ],
                                result=types.I32(),
                            ),
                            body=None,
                        ),
                        ast.Function(
                            name="sum",
                            is_exported=False,
                            params=[
                                ast.Param(
                                    name="self",
                                    type=types.Param(
                                        name="self",
                                        type=types.TypeRef(name="List")),
                                )
                            ],
                            type=types.Function(
                                name="sum",
                                params=[
                                    types.Param(
                                        name="self",
                                        type=types.TypeRef(name="List"))
                                ],
                                result=types.I32(),
                            ),
                            body=None,
                        ),
                    ],
                    type=types.Trait(name="List", functions=[]),
                )
            ],
            data_defs=[
                ast.DataDef(
                    name="EmptyList",
                    is_exported=False,
                    implements=["List"],
                    params=[],
                    functions=[
                        ast.Function(
                            name="length",
                            is_exported=False,
                            params=[
                                ast.Param(
                                    name="self",
                                    type=types.Param(
                                        name="self",
                                        type=types.TypeRef(name="List")),
                                )
                            ],
                            type=types.Function(
                                name="length",
                                params=[
                                    types.Param(
                                        name="self",
                                        type=types.TypeRef(name="List"))
                                ],
                                result=types.I32(),
                            ),
                            body=[ast.Number(value=0)],
                        ),
                        ast.Function(
                            name="sum",
                            is_exported=False,
                            params=[
                                ast.Param(
                                    name="self",
                                    type=types.Param(
                                        name="self",
                                        type=types.TypeRef(name="List")),
                                )
                            ],
                            type=types.Function(
                                name="sum",
                                params=[
                                    types.Param(
                                        name="self",
                                        type=types.TypeRef(name="List"))
                                ],
                                result=types.I32(),
                            ),
                            body=[ast.Number(value=0)],
                        ),
                    ],
                    type=types.Data(
                        name="EmptyList",
                        implements=[types.TypeRef("List")],
                        fields=[],
                        functions=[],
                    ),
                ),
                ast.DataDef(
                    name="Cons",
                    is_exported=False,
                    implements=["List"],
                    params=[
                        ast.Param(name="head",
                                  type=types.Field(name="head",
                                                   type=types.I32())),
                        ast.Param(
                            name="tail",
                            type=types.Field(name="tail",
                                             type=types.TypeRef(name="List")),
                        ),
                    ],
                    functions=[
                        ast.Function(
                            name="length",
                            is_exported=False,
                            params=[
                                ast.Param(
                                    name="self",
                                    type=types.Param(
                                        name="self",
                                        type=types.TypeRef(name="List")),
                                )
                            ],
                            type=types.Function(
                                name="length",
                                params=[
                                    types.Param(
                                        name="self",
                                        type=types.TypeRef(name="List"))
                                ],
                                result=types.I32(),
                            ),
                            body=[
                                ast.BinaryOperation(
                                    operator=ast.BinaryOperator.ADD,
                                    left=ast.Number(value=1),
                                    right=ast.FunctionCall(
                                        name="self.tail.length", arguments=[]),
                                )
                            ],
                        ),
                        ast.Function(
                            name="sum",
                            is_exported=False,
                            params=[
                                ast.Param(
                                    name="self",
                                    type=types.Param(
                                        name="self",
                                        type=types.TypeRef(name="List")),
                                )
                            ],
                            type=types.Function(
                                name="sum",
                                params=[
                                    types.Param(
                                        name="self",
                                        type=types.TypeRef(name="List"))
                                ],
                                result=types.I32(),
                            ),
                            body=[
                                ast.BinaryOperation(
                                    operator=ast.BinaryOperator.ADD,
                                    left=ast.MemberAccess(
                                        value=ast.Variable(name="self"),
                                        member="head"),
                                    right=ast.FunctionCall(
                                        name="self.tail.sum", arguments=[]),
                                )
                            ],
                        ),
                    ],
                    type=types.Data(
                        name="Cons",
                        implements=[types.TypeRef("List")],
                        fields=[
                            types.Field(name="head", type=types.I32()),
                            types.Field(name="tail",
                                        type=types.TypeRef(name="List")),
                        ],
                        functions=[],
                    ),
                ),
            ],
            functions=[],
        ),
    )
Esempio n. 17
0
def test_data_vector_with_complex_function():
    source = """
        import System::Output;

        export data Vector(x: i32, y: i32) {
            function add(self: Vector, other: Vector): Vector {
                Vector(x = self.x + other.x, y = self.y + other.y);
            }
        }

        export function Main(): void {

        }
     """
    result = get_semantic_analysis(source)

    assert_equal_programs(
        result,
        ast.Program(
            imports=[ast.Import(value="System::Output")],
            traits=[],
            data_defs=[
                ast.DataDef(
                    name="Vector",
                    implements=[],
                    is_exported=True,
                    params=[
                        ast.Param(name="x",
                                  type=types.Field(name="x",
                                                   type=types.I32())),
                        ast.Param(name="y",
                                  type=types.Field(name="y",
                                                   type=types.I32())),
                    ],
                    functions=[
                        ast.Function(
                            name="add",
                            is_exported=False,
                            params=[
                                ast.Param(
                                    name="self",
                                    type=types.Param(
                                        name="self",
                                        type=types.TypeRef(name="Vector")),
                                ),
                                ast.Param(
                                    name="other",
                                    type=types.Param(
                                        name="other",
                                        type=types.TypeRef(name="Vector")),
                                ),
                            ],
                            type=types.Function(
                                name="add",
                                params=[
                                    types.Param(
                                        name="self",
                                        type=types.TypeRef(name="Vector")),
                                    types.Param(
                                        name="other",
                                        type=types.TypeRef(name="Vector")),
                                ],
                                result=types.TypeRef(name="Vector"),
                            ),
                            body=[
                                ast.FunctionCall(
                                    name="Vector",
                                    arguments=[
                                        ast.Argument(
                                            name="x",
                                            value=ast.BinaryOperation(
                                                operator=ast.BinaryOperator.
                                                ADD,
                                                left=ast.MemberAccess(
                                                    value=ast.Variable(
                                                        name="self"),
                                                    member="x",
                                                ),
                                                right=ast.MemberAccess(
                                                    value=ast.Variable(
                                                        name="other"),
                                                    member="x",
                                                ),
                                            ),
                                        ),
                                        ast.Argument(
                                            name="y",
                                            value=ast.BinaryOperation(
                                                operator=ast.BinaryOperator.
                                                ADD,
                                                left=ast.MemberAccess(
                                                    value=ast.Variable(
                                                        name="self"),
                                                    member="y",
                                                ),
                                                right=ast.MemberAccess(
                                                    value=ast.Variable(
                                                        name="other"),
                                                    member="y",
                                                ),
                                            ),
                                        ),
                                    ],
                                )
                            ],
                        )
                    ],
                    type=types.Data(
                        name="Vector",
                        implements=[],
                        fields=[
                            types.Field(name="x", type=types.I32()),
                            types.Field(name="y", type=types.I32()),
                        ],
                        functions=[],
                    ),
                )
            ],
            functions=[
                ast.Function(
                    name="Main",
                    is_exported=True,
                    params=[],
                    type=types.Function(name="Main",
                                        params=[],
                                        result=types.Void()),
                    body=[],
                )
            ],
        ),
    )
Esempio n. 18
0
 def astFunction(*args):
     return ast.Function(None, *args)
Esempio n. 19
0
    def funcdef(self, nodelist):
        if len(nodelist) == 6:
            assert nodelist[0][0] == symbol.decorators
            decorators = self.decorators(nodelist[0][1:])
        else:
            assert len(nodelist) == 5
            decorators = None

        lineno = nodelist[-4][2]
        name = nodelist[-4][1]
        args = nodelist[-3][2]

        if not re.match('_q_((html|plain)_)?template_', name):
            # just a normal function, let base class handle it
            self.__template_type.append(None)
            n = transformer.Transformer.funcdef(self, nodelist)

        else:
            if name.startswith(PLAIN_TEMPLATE_PREFIX):
                name = name[len(PLAIN_TEMPLATE_PREFIX):]
                template_type = "plain"
            elif name.startswith(HTML_TEMPLATE_PREFIX):
                name = name[len(HTML_TEMPLATE_PREFIX):]
                template_type = "html"
            elif name.startswith(TEMPLATE_PREFIX):
                name = name[len(TEMPLATE_PREFIX):]
                template_type = "plain"
            else:
                raise RuntimeError, 'unknown prefix on %s' % name

            self.__template_type.append(template_type)

            # Add "IO_INSTANCE = IO_CLASS()" statement at the beginning of
            # the function and a "return IO_INSTANCE" at the end.
            if args[0] == symbol.varargslist:
                names, defaults, flags = self.com_arglist(args[1:])
            else:
                names = defaults = ()
                flags = 0
            doc = None  # self.get_docstring(nodelist[-1])

            # code for function
            code = self.com_node(nodelist[-1])

            # create an instance, assign to IO_INSTANCE
            klass = ast.Name(IO_CLASS)
            args = [ast.Const(template_type == "html")]
            instance = ast.CallFunc(klass, args)
            assign_name = ast.AssName(IO_INSTANCE, OP_ASSIGN)
            assign = ast.Assign([assign_name], instance)

            # return the IO_INSTANCE.getvalue(...)
            func = ast.Getattr(ast.Name(IO_INSTANCE), "getvalue")
            ret = ast.Return(ast.CallFunc(func, []))

            # wrap original function code
            code = ast.Stmt([assign, code, ret])

            if sys.hexversion >= 0x20400a2:
                n = ast.Function(decorators, name, names, defaults, flags, doc,
                                 code)
            else:
                n = ast.Function(name, names, defaults, flags, doc, code)
            n.lineno = lineno

        self.__template_type.pop()
        return n