From: David Kerkeslager Date: Sat, 12 Aug 2017 18:28:22 +0000 (-0400) Subject: Allow the results of function calls to be immediately called X-Git-Url: https://code.kerkeslager.com/?a=commitdiff_plain;h=06df4340fb0920f2c9d1967300be517d88cf0ca1;p=fur Allow the results of function calls to be immediately called --- diff --git a/examples/24_function_calls_for_functions.fur b/examples/24_function_calls_for_functions.fur new file mode 100644 index 0000000..bebadb9 --- /dev/null +++ b/examples/24_function_calls_for_functions.fur @@ -0,0 +1,10 @@ +def make_incrementer(increment_amount) do + def result(i) do + increment_amount + i + end + + result +end + +print(make_incrementer(1)(41), '\n') +print(make_incrementer(2)(40), '\n') diff --git a/examples/24_function_calls_for_functions.fur.output.txt b/examples/24_function_calls_for_functions.fur.output.txt new file mode 100644 index 0000000..daaac9e --- /dev/null +++ b/examples/24_function_calls_for_functions.fur.output.txt @@ -0,0 +1,2 @@ +42 +42 diff --git a/parsing.py b/parsing.py index 7240b52..82c6528 100644 --- a/parsing.py +++ b/parsing.py @@ -96,27 +96,33 @@ def _symbol_expression_parser(index, tokens): return (False, index, None) -def _parenthesized_expression_parser(index, tokens): - failure = (False, index, None) +def _parenthese_wrapped_parser(internal_parser): + def result_parser(index, tokens): + failure = (False, index, None) - if tokens[index].type == 'open_parenthese': - index += 1 - else: - return failure + if tokens[index].type == 'open_parenthese': + index += 1 + else: + return failure - success, index, internal = _expression_parser(index, tokens) - if not success: - return failure + success, index, internal = internal_parser(index, tokens) + if not success: + return failure - if tokens[index].type == 'close_parenthese': - index += 1 - else: - raise Exception('Expected ")" on line {}, found "{}"'.format( - tokens[index].line, - tokens[index].match, - )) + if tokens[index].type == 'close_parenthese': + index += 1 + else: + raise Exception('Expected ")" on line {}, found "{}"'.format( + tokens[index].line, + tokens[index].match, + )) + + return True, index, internal - return True, index, internal + return result_parser + +def _parenthesized_expression_parser(index, tokens): + return _parenthese_wrapped_parser(_expression_parser)(index, tokens) def _negation_expression_parser(index, tokens): failure = (False, index, None) @@ -274,8 +280,6 @@ FurProgram = collections.namedtuple( ) def _function_call_expression_parser(index, tokens): - # TODO Allow function calls as the source of the function. This requires a - # left-recursive parser, however. failure = (False, index, None) # We have to be careful what expressions we add here. Otherwise expressions @@ -288,23 +292,28 @@ def _function_call_expression_parser(index, tokens): if not success: return failure - if tokens[index].type != 'open_parenthese': - return failure - index += 1 - - success, index, arguments = _comma_separated_expression_list_parser(index, tokens) + success, index, arguments = _parenthese_wrapped_parser(_comma_separated_expression_list_parser)( + index, + tokens, + ) if not success: return failure - if tokens[index].type != 'close_parenthese': - raise Exception('Expected ")", found "{}" on line {}'.format( - tokens[index].match, - tokens[index].line, - )) - index += 1 + while success and index < len(tokens): + # "function" is actually the full function call if the next parse attempt doesn't succeed + # We can't give this a better name without a bunch of checks, however. + function = FurFunctionCallExpression( + function=function, + arguments=arguments, + ) + + success, index, arguments = _parenthese_wrapped_parser(_comma_separated_expression_list_parser)( + index, + tokens, + ) - return True, index, FurFunctionCallExpression(function=function, arguments=arguments) + return True, index, function _expression_parser = _or_level_expression_parser