From 328947882d63d9d4f2ead0dbc54bee33bef6c33b Mon Sep 17 00:00:00 2001 From: David Kerkeslager Date: Sun, 24 Sep 2017 18:08:20 -0400 Subject: [PATCH] Add very rudimentary line numbers to exceptions --- examples/30_division_by_zero.fur.stderr.txt | 2 +- generation.py | 3 ++- normalization.py | 5 +++++ parsing.py | 13 +++++++++++++ templates/program.c | 6 +++--- transformation.py | 3 +++ 6 files changed, 27 insertions(+), 5 deletions(-) diff --git a/examples/30_division_by_zero.fur.stderr.txt b/examples/30_division_by_zero.fur.stderr.txt index b1f79c7..9d45c1d 100644 --- a/examples/30_division_by_zero.fur.stderr.txt +++ b/examples/30_division_by_zero.fur.stderr.txt @@ -1,3 +1,3 @@ -DivisionByZeroError +DivisionByZeroError on line 2 in get_divided_answer in __main__ diff --git a/generation.py b/generation.py index 44a8d16..64554d0 100644 --- a/generation.py +++ b/generation.py @@ -27,8 +27,9 @@ def generate_variable_expression(expression): return expression.variable def generate_function_call_for_fur_infix_operator(expression): - return 'operator${}(stack, jump)'.format( + return 'operator${}(stack, jump, {})'.format( expression.name, + expression.metadata.line, ) def generate_structure_literal_expression(expression): diff --git a/normalization.py b/normalization.py index 9da90d7..f2b7b13 100644 --- a/normalization.py +++ b/normalization.py @@ -49,6 +49,7 @@ NormalDotExpression = collections.namedtuple( NormalInfixExpression = collections.namedtuple( 'NormalInfixExpression', [ + 'metadata', 'order', 'operator', ], @@ -405,6 +406,7 @@ def normalize_basic_infix_operation(counter, expression): NormalVariableInitializationStatement( variable=center_variable, expression=NormalInfixExpression( + metadata=expression.metadata, order=expression.order, operator=expression.operator, ), @@ -441,15 +443,18 @@ def desugar_ternary_comparison(counter, expression): counter, boolean_expression_prestatements, boolean_expression = normalize_boolean_expression( counter, parsing.FurInfixExpression( + metadata=expression.left.metadata, order='and_level', operator='and', left=parsing.FurInfixExpression( + metadata=expression.left.metadata, order='comparison_level', operator=expression.left.operator, left=NormalVariableExpression(variable=left_variable), right=NormalVariableExpression(variable=middle_variable), ), right=parsing.FurInfixExpression( + metadata=expression.metadata, order='comparison_level', operator=expression.operator, left=NormalVariableExpression(variable=middle_variable), diff --git a/parsing.py b/parsing.py index 2076837..12b93f5 100644 --- a/parsing.py +++ b/parsing.py @@ -36,6 +36,14 @@ def _zero_or_more_parser(formatter, parser): return result_parser +NodeMetadata = collections.namedtuple( + 'NodeMetadata', + [ + 'index', + 'line', + ], +) + FurIntegerLiteralExpression = collections.namedtuple( 'FurIntegerLiteralExpression', [ @@ -67,6 +75,7 @@ FurNegationExpression = collections.namedtuple( FurInfixExpression = collections.namedtuple( 'FurInfixExpression', [ + 'metadata', 'order', 'operator', 'left', @@ -270,6 +279,10 @@ def _left_recursive_infix_operator_parser(operator_token_matcher, operand_parser if success: result = FurInfixExpression( + metadata=NodeMetadata( + index=tokens[index].index, + line=tokens[index].line, + ), order=order, operator=tokens[index].match, left=result, diff --git a/templates/program.c b/templates/program.c index 18d8616..08921b1 100644 --- a/templates/program.c +++ b/templates/program.c @@ -545,7 +545,7 @@ Object operator$negate(Object input) } // TODO Make this conditionally added -Object operator$concatenate(Stack* stack, jmp_buf parent_jump) +Object operator$concatenate(Stack* stack, jmp_buf parent_jump, size_t line) { Object right = Stack_pop(stack); Object left = Stack_pop(stack); @@ -578,7 +578,7 @@ Object operator$concatenate(Stack* stack, jmp_buf parent_jump) } {% for id in infix_declarations %} -Object operator${{ id.name }}(Stack* stack, jmp_buf parent_jump) +Object operator${{ id.name }}(Stack* stack, jmp_buf parent_jump, size_t line) { Object right = Stack_pop(stack); Object left = Stack_pop(stack); @@ -589,7 +589,7 @@ Object operator${{ id.name }}(Stack* stack, jmp_buf parent_jump) {% if id.name == 'integerDivide' or id.name == 'modularDivide' %} if(right.instance.integer == 0) { - fprintf(stderr, "DivisionByZeroError\n"); + fprintf(stderr, "DivisionByZeroError on line %zu\n", line); longjmp(parent_jump, 1); } {% endif %} diff --git a/transformation.py b/transformation.py index 6a5354b..7d47ed4 100644 --- a/transformation.py +++ b/transformation.py @@ -61,6 +61,7 @@ CNegationExpression = collections.namedtuple( CFunctionCallForFurInfixOperator = collections.namedtuple( 'CFunctionCallForFurInfixOperator', [ + 'metadata', 'name', ], ) @@ -240,6 +241,7 @@ FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR = { def transform_infix_operator_without_c_equivalent(accumulators, expression): return CFunctionCallForFurInfixOperator( + metadata=expression.metadata, name='concatenate', ) @@ -250,6 +252,7 @@ def transform_infix_expression(accumulators, expression): accumulators.operator_set.add(FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator]) return CFunctionCallForFurInfixOperator( + metadata=expression.metadata, name=FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator].name, ) -- 2.20.1