From 6b38b7cc077425e4366eaea2813e19c2a1fb15d0 Mon Sep 17 00:00:00 2001 From: David Kerkeslager Date: Sat, 6 Jan 2018 15:12:55 -0500 Subject: [PATCH] Add support for nested functions with the same name in different contexts --- examples/31_nested_functions_same_name.fur | 18 +++++++++++++++ ..._nested_functions_same_name.fur.stdout.txt | 2 ++ generation.py | 4 +++- templates/function_definition.c | 2 +- transformation.py | 23 +++++++++++-------- 5 files changed, 37 insertions(+), 12 deletions(-) create mode 100644 examples/31_nested_functions_same_name.fur create mode 100644 examples/31_nested_functions_same_name.fur.stdout.txt diff --git a/examples/31_nested_functions_same_name.fur b/examples/31_nested_functions_same_name.fur new file mode 100644 index 0000000..3cbeb0c --- /dev/null +++ b/examples/31_nested_functions_same_name.fur @@ -0,0 +1,18 @@ +def get_incrementer(n) do + def foo(m) do + m + n + end + + foo +end + +def get_multiplier(n) do + def foo(m) do + m * n + end + + foo +end + +print(get_incrementer(2)(3), '\n') +print(get_multiplier(2)(3), '\n') diff --git a/examples/31_nested_functions_same_name.fur.stdout.txt b/examples/31_nested_functions_same_name.fur.stdout.txt new file mode 100644 index 0000000..6613b56 --- /dev/null +++ b/examples/31_nested_functions_same_name.fur.stdout.txt @@ -0,0 +1,2 @@ +5 +6 diff --git a/generation.py b/generation.py index 74a3fa5..e167f25 100644 --- a/generation.py +++ b/generation.py @@ -34,8 +34,9 @@ def generate_structure_literal_expression(expression): ) def generate_lambda_expression(expression): - return '(Object){{ CLOSURE, (Instance)(Closure){{ environment, user${}$implementation }} }}'.format( + return '(Object){{ CLOSURE, (Instance)(Closure){{ environment, user${}${}$implementation }} }}'.format( expression.name, + expression.index, ) def generate_list_construct_expression(expression): @@ -165,6 +166,7 @@ def generate_function_definition(definition): template = ENV.get_template('function_definition.c') return template.render( name=definition.name, + index=definition.index, argument_name_list=definition.argument_name_list, statement_list=list(generate_statement(s) for s in definition.statement_list), ) diff --git a/templates/function_definition.c b/templates/function_definition.c index 034a2af..ccf3e75 100644 --- a/templates/function_definition.c +++ b/templates/function_definition.c @@ -1,5 +1,5 @@ -Object user${{name}}$implementation( +Object user${{name}}${{index}}$implementation( EnvironmentPool* environmentPool, Environment* environment, size_t argc, diff --git a/transformation.py b/transformation.py index 6f46d43..a9cad95 100644 --- a/transformation.py +++ b/transformation.py @@ -122,6 +122,7 @@ CFunctionDefinition = collections.namedtuple( 'CFunctionDefinition', [ 'name', + 'index', 'argument_name_list', 'statement_list', ], @@ -192,6 +193,7 @@ CLambdaExpression = collections.namedtuple( 'CLambdaExpression', ( 'name', + 'index', ), ) @@ -211,24 +213,25 @@ def transform_structure_literal_expression(accumulators, expression): ) def transform_lambda_expression(accumulators, expression): - # TODO This function feels hacky - if len(accumulators.lambda_number_list) == 0: - accumulators.lambda_number_list.append(0) - else: - accumulators.lambda_number_list.append(accumulators.lambda_number_list[-1] + 1) - if expression.name is None: - name = '__lambda_{}'.format(accumulators.lambda_number_list[-1]) + name = '__lambda' else: name = expression.name + index = accumulators.function_name_iterators.get(name, 0) + accumulators.function_name_iterators[name] = index + 1 + accumulators.function_definition_list.append(CFunctionDefinition( name=name, + index=index, argument_name_list=expression.argument_name_list, statement_list=tuple(transform_statement(accumulators, s) for s in expression.statement_list), )) - return CLambdaExpression(name=name) + return CLambdaExpression( + name=name, + index=index, + ) def transform_list_construct_expression(accumulators, expression): @@ -347,7 +350,7 @@ Accumulators = collections.namedtuple( [ 'builtin_set', 'function_definition_list', - 'lambda_number_list', + 'function_name_iterators', 'operator_set', 'symbol_list', 'string_literal_list', @@ -358,7 +361,7 @@ def transform(program): accumulators = Accumulators( builtin_set=set(), function_definition_list=[], - lambda_number_list=[], + function_name_iterators={}, operator_set=set(), symbol_list=[], string_literal_list=[], -- 2.20.1