Add very rudimentary line numbers to exceptions
authorDavid Kerkeslager <kerkeslager@gmail.com>
Sun, 24 Sep 2017 22:08:20 +0000 (18:08 -0400)
committerDavid Kerkeslager <kerkeslager@gmail.com>
Sun, 24 Sep 2017 22:08:20 +0000 (18:08 -0400)
examples/30_division_by_zero.fur.stderr.txt
generation.py
normalization.py
parsing.py
templates/program.c
transformation.py

index b1f79c7..9d45c1d 100644 (file)
@@ -1,3 +1,3 @@
-DivisionByZeroError
+DivisionByZeroError on line 2
        in get_divided_answer
        in __main__
index 44a8d16..64554d0 100644 (file)
@@ -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):
index 9da90d7..f2b7b13 100644 (file)
@@ -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),
index 2076837..12b93f5 100644 (file)
@@ -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,
index 18d8616..08921b1 100644 (file)
@@ -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 %}
index 6a5354b..7d47ed4 100644 (file)
@@ -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,
     )