From 5d679d88b539fe29d59635bca2fdcc796bed3da8 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Mon, 21 Dec 2020 10:08:05 +0800 Subject: [PATCH] if exprssion --- toy-impl/parse_expr.py | 21 ++++++++++++++++++--- toy-impl/test_expr.py | 3 +++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/toy-impl/parse_expr.py b/toy-impl/parse_expr.py index 9d3f80d..f673bc1 100644 --- a/toy-impl/parse_expr.py +++ b/toy-impl/parse_expr.py @@ -38,6 +38,8 @@ def parse_expr(ctx: Context, return parse_call(ctx, sym_table, body) if isinstance(body, ast.Subscript): return parse_subscript(ctx, sym_table, body) + if isinstance(body, ast.IfExp): + return parse_if_expr(ctx, sym_table, body) raise CustomError(f'{body} is not yet supported') @@ -65,10 +67,10 @@ def parse_constant(ctx: Context, sym_table: dict[str, Type], node): v = node.value - if isinstance(v, int): - return ctx.types['int32'] - elif isinstance(v, bool): + if isinstance(v, bool): return ctx.types['bool'] + elif isinstance(v, int): + return ctx.types['int32'] else: raise CustomError(f'unknown constant {v}') @@ -189,3 +191,16 @@ def parse_subscript(ctx: Context, else: raise CustomError(f'index of type {s} is not supported') +def parse_if_expr(ctx: Context, + sym_table: dict[str, Type], + node): + b = ctx.types['bool'] + t = parse_expr(ctx, sym_table, node.test) + if t != b: + raise CustomError(f'type of conditional must be bool instead of {t}') + ty1 = parse_expr(ctx, sym_table, node.body) + ty2 = parse_expr(ctx, sym_table, node.orelse) + if ty1 != ty2: + raise CustomError(f'divergent type for if expression: {ty1} != {ty2}') + return ty1 + diff --git a/toy-impl/test_expr.py b/toy-impl/test_expr.py index d43ff9b..5794a8e 100644 --- a/toy-impl/test_expr.py +++ b/toy-impl/test_expr.py @@ -76,6 +76,9 @@ test_expr('[1,2,3][:a:2]', {'a': I}) test_expr('[1,2,3][:a:2]', {'a': i32}) test_expr('a == a == a', {'a': I}) test_expr('a == a and 1 == 2', {'a': I}) +test_expr('1 if a == b else 0', {'a': I, 'b': I}) +test_expr('a if a == b else 1', {'a': I, 'b': I}) +test_expr('a if a == b else b', {'a': I, 'b': I}) test_classes = """ class Foo: