From: David Kerkeslager Date: Fri, 25 Aug 2017 03:52:21 +0000 (-0400) Subject: Add double-quoted strings X-Git-Url: https://code.kerkeslager.com/?a=commitdiff_plain;h=02d64def49065ad614fe0ee2a85060666552192e;p=fur Add double-quoted strings --- diff --git a/examples/28_double_quoted_strings.fur b/examples/28_double_quoted_strings.fur new file mode 100644 index 0000000..811c474 --- /dev/null +++ b/examples/28_double_quoted_strings.fur @@ -0,0 +1,2 @@ +print("Don't stop me now\n") +print('"Cogito ergo sum." --Descartes\n') diff --git a/examples/28_double_quoted_strings.fur.output.txt b/examples/28_double_quoted_strings.fur.output.txt new file mode 100644 index 0000000..f9f104d --- /dev/null +++ b/examples/28_double_quoted_strings.fur.output.txt @@ -0,0 +1,2 @@ +Don't stop me now +"Cogito ergo sum." --Descartes diff --git a/generation.py b/generation.py index bc2e2c1..99fd681 100644 --- a/generation.py +++ b/generation.py @@ -168,6 +168,16 @@ def generate_function_definition(definition): ) return definition +C_ESCAPES = { + '"': r'\"', +} + +def escape_character(ch): + return C_ESCAPES.get(ch, ch) + +def escape_string_literal(string_literal): + return ''.join(escape_character(ch) for ch in string_literal) + def generate(program): template = ENV.get_template('program.c') return template.render( @@ -176,7 +186,7 @@ def generate(program): infix_declarations=program.operator_declarations, statements=list(generate_statement(s) for s in program.statements), standard_libraries=list(sorted(program.standard_libraries)), - string_literal_list=program.string_literal_list, + string_literal_list=list(escape_string_literal(s) for s in program.string_literal_list), symbol_list=program.symbol_list, ) diff --git a/normalization.py b/normalization.py index fbe3d04..762a8f1 100644 --- a/normalization.py +++ b/normalization.py @@ -587,12 +587,12 @@ def normalize_statement_list(counter, statement_list, **kwargs): result_statement_list.append(s) result_statement_list.append(normalized) + # TODO The way we fix the last statement is really confusing last_statement = result_statement_list[-1] if isinstance(last_statement, NormalExpressionStatement) and isinstance(last_statement.expression, NormalVariableExpression): - result_expression = result_statement_list.pop().expression - if assign_result_to is not None: + result_expression = result_statement_list.pop().expression result_statement_list.append( NormalVariableReassignmentStatement( variable=assign_result_to, diff --git a/parsing.py b/parsing.py index 45964d7..f16af14 100644 --- a/parsing.py +++ b/parsing.py @@ -101,6 +101,9 @@ def _integer_literal_expression_parser(index, tokens): return True, index, FurIntegerLiteralExpression(integer=value) def _string_literal_expression_parser(index, tokens): + if tokens[index].type == 'double_quoted_string_literal': + return (True, index + 1, FurStringLiteralExpression(string=tokens[index].match[1:-1])) + if tokens[index].type == 'single_quoted_string_literal': return (True, index + 1, FurStringLiteralExpression(string=tokens[index].match[1:-1])) diff --git a/tokenization.py b/tokenization.py index 33f4331..02f9528 100644 --- a/tokenization.py +++ b/tokenization.py @@ -41,6 +41,7 @@ _TOKEN_MATCHERS = [ ('integer_literal', r'\d+'), ('symbol', r'[a-z_]+'), ('single_quoted_string_literal', r"'.*?'"), + ('double_quoted_string_literal', r'".*?"'), ('comparison_level_operator', r'(<=|>=|==|!=|<|>)'), ('assignment_operator', r'='), ('addition_level_operator', r'(\+\+|\+|-)'), diff --git a/transformation.py b/transformation.py index e06bcf0..1a9f2c6 100644 --- a/transformation.py +++ b/transformation.py @@ -432,11 +432,6 @@ def transform(program): transform_statement(accumulators, statement) for statement in program.statement_list ] - # This prevents warnings about normalized variables being entire C statements - last_statement = statement_list[-1] - if isinstance(last_statement, normalization.NormalExpressionStatement) and isinstance(last_statement.expression, normalization.NormalVariableExpression): - del statement_list[-1] - standard_library_set = set() for builtin in accumulators.builtin_set: for standard_library in BUILTINS[builtin]: