Example #1
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),
                                ),
                            ),
                        )
                    ],
                )
            ],
        ),
    )
Example #2
0
    def visit_function(self, function: ast.Function):
        """
        Visit the function definition, populating the return and param type information.
        During this stage the function body is skipped, as it may depend on types defined
        later within the file
        """

        param_types = []
        for param in function.params:
            param.type = types.Param(
                name=param.name, type=as_language_type(param.type, self.symbol_table)
            )
            param_types.append(param.type)

        function.type = types.Function(
            name=function.name,
            result=as_language_type(function.type, self.symbol_table),
            params=param_types,
        )
        function_symbol = Symbol(
            name=function.name, type=function.type, kind=SymbolKind.FUNC
        )
        self.symbol_table.add(function_symbol)
        return function
Example #3
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"),
                        )
                    ],
                ),
            ],
        ),
    )
Example #4
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=[],
        ),
    )
Example #5
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=[],
                )
            ],
        ),
    )