From 0a83b51e00a1de48c830d8c889742dabdd81f585 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 27 Jun 2023 01:59:22 +0200 Subject: [PATCH] allow more curly brace styles --- compiler/test/ModuleImporterTests.kt | 8 ++-- compiler/test/ast/TestProg8Parser.kt | 2 +- compiler/test/ast/TestVariousCompilerAst.kt | 45 +++++++++++++++++++ .../fixtures/ast_file_with_syntax_error.p8 | 2 +- .../test/fixtures/file_with_syntax_error.p8 | 2 +- docs/source/syntaxreference.rst | 2 - docs/source/todo.rst | 5 --- examples/test.p8 | 31 +++++++++---- parser/antlr/Prog8ANTLR.g4 | 6 +-- 9 files changed, 78 insertions(+), 25 deletions(-) diff --git a/compiler/test/ModuleImporterTests.kt b/compiler/test/ModuleImporterTests.kt index 9e5af853d..8e008b7e6 100644 --- a/compiler/test/ModuleImporterTests.kt +++ b/compiler/test/ModuleImporterTests.kt @@ -151,7 +151,7 @@ class TestModuleImporter: FunSpec({ shouldThrow { act() }.let { it.position.file shouldBe SourceCode.relative(srcPath).toString() withClue("line; should be 1-based") { it.position.line shouldBe 2 } - withClue("startCol; should be 0-based") { it.position.startCol shouldBe 6 } + withClue("startCol; should be 0-based") { it.position.startCol shouldBe 4 } withClue("endCol; should be 0-based") { it.position.endCol shouldBe 6 } } } @@ -171,7 +171,7 @@ class TestModuleImporter: FunSpec({ shouldThrow { act() }.let { it.position.file shouldBe SourceCode.relative(imported).toString() withClue("line; should be 1-based") { it.position.line shouldBe 2 } - withClue("startCol; should be 0-based") { it.position.startCol shouldBe 6 } + withClue("startCol; should be 0-based") { it.position.startCol shouldBe 4 } withClue("endCol; should be 0-based") { it.position.endCol shouldBe 6 } } } @@ -231,7 +231,7 @@ class TestModuleImporter: FunSpec({ importer.importImplicitLibraryModule(srcPath.nameWithoutExtension) }.let { it.position.file shouldBe SourceCode.relative(srcPath).toString() withClue("line; should be 1-based") { it.position.line shouldBe 2 } - withClue("startCol; should be 0-based") { it.position.startCol shouldBe 6 } + withClue("startCol; should be 0-based") { it.position.startCol shouldBe 4 } withClue("endCol; should be 0-based") { it.position.endCol shouldBe 6 } } } @@ -253,7 +253,7 @@ class TestModuleImporter: FunSpec({ act() }.let { it.position.file shouldBe SourceCode.relative(imported).toString() withClue("line; should be 1-based") { it.position.line shouldBe 2 } - withClue("startCol; should be 0-based") { it.position.startCol shouldBe 6 } + withClue("startCol; should be 0-based") { it.position.startCol shouldBe 4 } withClue("endCol; should be 0-based") { it.position.endCol shouldBe 6 } } } diff --git a/compiler/test/ast/TestProg8Parser.kt b/compiler/test/ast/TestProg8Parser.kt index ec6d4de6f..14d36b9c2 100644 --- a/compiler/test/ast/TestProg8Parser.kt +++ b/compiler/test/ast/TestProg8Parser.kt @@ -274,7 +274,7 @@ class TestProg8Parser: FunSpec( { val path = assumeReadableFile(fixturesDir, "ast_file_with_syntax_error.p8") val e = shouldThrow { parseModule(SourceCode.File(path)) } - assertPosition(e.position, SourceCode.relative(path).toString(), 2, 6) + assertPosition(e.position, SourceCode.relative(path).toString(), 2, 4) } test("of Module parsed from a string") { diff --git a/compiler/test/ast/TestVariousCompilerAst.kt b/compiler/test/ast/TestVariousCompilerAst.kt index a3d0cdaa0..c18a63179 100644 --- a/compiler/test/ast/TestVariousCompilerAst.kt +++ b/compiler/test/ast/TestVariousCompilerAst.kt @@ -275,5 +275,50 @@ main { errors.errors[0] shouldContain "invalid statement in unroll loop" errors.errors[1] shouldContain "invalid statement in unroll loop" } + + test("various curly brace styles") { + val src=""" +main +{ + sub start() + { + ubyte variable=55 + when variable + { + 33 -> cx16.r0++ + else -> cx16.r1++ + } + + if variable { + cx16.r0++ + } else { + cx16.r1++ + } + + if variable { cx16.r0++ } + else { cx16.r1++ } + + if variable + { + cx16.r0++ + } + else + { + cx16.r1++ + } + + other.othersub() + } +} + + +other { + sub othersub() { + cx16.r0++ + } +}""" + + compileText(VMTarget(), optimize=false, src, writeAssembly=false) shouldNotBe null + } }) diff --git a/compiler/test/fixtures/ast_file_with_syntax_error.p8 b/compiler/test/fixtures/ast_file_with_syntax_error.p8 index 6b9930fe0..dcb65cb34 100644 --- a/compiler/test/fixtures/ast_file_with_syntax_error.p8 +++ b/compiler/test/fixtures/ast_file_with_syntax_error.p8 @@ -1,2 +1,2 @@ ; test expects the following 2nd (!) line: -bad { } ; -> missing EOL at '}' (ie: *after* the '{') +bad bad bad { } } } diff --git a/compiler/test/fixtures/file_with_syntax_error.p8 b/compiler/test/fixtures/file_with_syntax_error.p8 index 6b9930fe0..dcb65cb34 100644 --- a/compiler/test/fixtures/file_with_syntax_error.p8 +++ b/compiler/test/fixtures/file_with_syntax_error.p8 @@ -1,2 +1,2 @@ ; test expects the following 2nd (!) line: -bad { } ; -> missing EOL at '}' (ie: *after* the '{') +bad bad bad { } } } diff --git a/docs/source/syntaxreference.rst b/docs/source/syntaxreference.rst index c15edbd5e..722c14955 100644 --- a/docs/source/syntaxreference.rst +++ b/docs/source/syntaxreference.rst @@ -621,8 +621,6 @@ The syntax is:: return X * 3 } -The open curly brace must immediately follow the subroutine result specification on the same line, -and can have nothing following it. The close curly brace must be on its own line as well. The parameters is a (possibly empty) comma separated list of " " pairs specifying the input parameters. The return type has to be specified if the subroutine returns a value. diff --git a/docs/source/todo.rst b/docs/source/todo.rst index c7ecc743d..d28f97d31 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,11 +1,6 @@ TODO ==== -- also allow this? - if variable { txt.print("yes") } - else { txt.print("no") } -- is it possible to allow the curly brace to be on the next line instead of requiring it to follow on the same line? - ... diff --git a/examples/test.p8 b/examples/test.p8 index cbeffe534..5ecc1f051 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,24 +1,39 @@ -%import textio -%zeropage basicsafe - -main { - +main +{ sub start() { ubyte variable=55 when variable { - 33 -> txt.print("33") + 33 -> cx16.r0++ + else -> cx16.r1++ } + if variable { + cx16.r0++ + } else { + cx16.r1++ + } + + if variable { cx16.r0++ } + else { cx16.r1++ } + if variable { - txt.print("yes") + cx16.r0++ } else { - txt.print("no") + cx16.r1++ } + + other.othersub() } } + +other { + sub othersub() { + cx16.r0++ + } +} diff --git a/parser/antlr/Prog8ANTLR.g4 b/parser/antlr/Prog8ANTLR.g4 index 07163f3a3..b299793a6 100644 --- a/parser/antlr/Prog8ANTLR.g4 +++ b/parser/antlr/Prog8ANTLR.g4 @@ -66,7 +66,7 @@ ARRAYSIG : // Note: the parser may see *several* consecutive EOLs - this happens when EOL and comments are interleaved (see #47) module: EOL* ((directive | block) (EOL+ (directive | block))*)? EOL* EOF; -block: identifier integerliteral? '{' EOL (block_statement | EOL)* '}'; +block: identifier integerliteral? EOL? '{' EOL? (block_statement | EOL)* '}'; block_statement: directive @@ -245,7 +245,7 @@ subroutine : sub_return_part : '->' datatype ; statement_block : - '{' EOL + '{' EOL? (statement | EOL) * '}' ; @@ -296,6 +296,6 @@ repeatloop: 'repeat' expression? EOL? (statement | statement_block) ; unrollloop: 'unroll' integerliteral? EOL? (statement | statement_block) ; -whenstmt: 'when' expression EOL? '{' EOL (when_choice | EOL) * '}' EOL? ; +whenstmt: 'when' expression EOL? '{' EOL? (when_choice | EOL) * '}' EOL? ; when_choice: (expression_list | 'else' ) '->' (statement | statement_block ) ;