From 59126f60cc52f0a9bdb5ff2a21d266974e6b6211 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sun, 21 Aug 2022 02:40:04 -0400 Subject: [PATCH 1/8] Added enum sections to tree --- parser/tree-tostring.go | 34 ++++++++++++++++++++++++++++++++++ parser/tree.go | 11 +++++++++++ 2 files changed, 45 insertions(+) diff --git a/parser/tree-tostring.go b/parser/tree-tostring.go index d469ed3..a26c6c9 100644 --- a/parser/tree-tostring.go +++ b/parser/tree-tostring.go @@ -56,6 +56,11 @@ func (tree *SyntaxTree) ToString (indent int) (output string) { output += tree.objtSections[name].ToString(indent) } + enumSectionKeys := sortMapKeysAlphabetically(tree.enumSections) + for _, name := range enumSectionKeys { + output += tree.enumSections[name].ToString(indent) + } + dataSectionKeys := sortMapKeysAlphabetically(tree.dataSections) for _, name := range dataSectionKeys { output += tree.dataSections[name].ToString(indent) @@ -319,3 +324,32 @@ func (section *ObjtSection) ToString (indent int) (output string) { return } +func (section *EnumSection) ToString (indent int) (output string) { + output += doIndent ( + indent, + "enum ", + section.permission.ToString(), " ", + section.name, ":", + section.what.ToString(), "\n") + + for _, name := range sortMapKeysAlphabetically(section.members) { + output += doIndent(indent, name, " ") + + member := section.members[name] + + isComplexInitialization := + member.kind == ArgumentKindObjectInitializationValues || + member.kind == ArgumentKindArrayInitializationValues + + if member.value == nil { + output += "\n" + } else if isComplexInitialization { + output += "\n" + output += member.ToString(indent + 1, true) + } else { + output += " " + member.ToString(0, false) + output += "\n" + } + } + return +} diff --git a/parser/tree.go b/parser/tree.go index c1b5e74..f5cf332 100644 --- a/parser/tree.go +++ b/parser/tree.go @@ -13,6 +13,7 @@ type SyntaxTree struct { requires []string typeSections map[string] *TypeSection objtSections map[string] *ObjtSection + enumSections map[string] *EnumSection dataSections map[string] *DataSection } @@ -191,3 +192,13 @@ type ObjtSection struct { permission types.Permission members map[string] ObjtMember } + +// EnumSection represents an enumerated type section. +type EnumSection struct { + location file.Location + name string + + what Type + permission types.Permission + members map[string] Argument +} From 6fbda3430032f982580ed7521caccb9287b31051 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sun, 21 Aug 2022 02:42:25 -0400 Subject: [PATCH 2/8] Add base enum parsing method --- parser/body.go | 8 ++++++++ parser/enum.go | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 parser/enum.go diff --git a/parser/body.go b/parser/body.go index 82b2635..a5bf767 100644 --- a/parser/body.go +++ b/parser/body.go @@ -40,6 +40,14 @@ func (parser *ParsingOperation) parseBody () (err error) { if err != nil { return } case "face": case "enum": + var section *EnumSection + section, err = parser.parseEnumSection() + if parser.tree.enumSections == nil { + parser.tree.enumSections = + make(map[string] *EnumSection) + } + parser.tree.enumSections[section.name] = section + if err != nil { return } case "func": default: err = parser.token.NewError ( diff --git a/parser/enum.go b/parser/enum.go new file mode 100644 index 0000000..0618df8 --- /dev/null +++ b/parser/enum.go @@ -0,0 +1,52 @@ +package parser + +import "git.tebibyte.media/sashakoshka/arf/types" +import "git.tebibyte.media/sashakoshka/arf/lexer" +import "git.tebibyte.media/sashakoshka/arf/infoerr" + +func (parser *ParsingOperation) parseEnumSection () ( + section *EnumSection, + err error, +) { + err = parser.expect(lexer.TokenKindName) + if err != nil { return } + + section = &EnumSection { + location: parser.token.Location(), + members: make(map[string] Argument), + } + + // get permission + err = parser.nextToken(lexer.TokenKindPermission) + if err != nil { return } + section.permission = parser.token.Value().(types.Permission) + + // get name + err = parser.nextToken(lexer.TokenKindName) + if err != nil { return } + section.name = parser.token.Value().(string) + + // parse inherited type + err = parser.nextToken(lexer.TokenKindColon) + if err != nil { return } + err = parser.nextToken() + if err != nil { return } + section.what, err = parser.parseType() + if err != nil { return } + err = parser.expect(lexer.TokenKindNewline) + if err != nil { return } + err = parser.nextToken() + if err != nil { return } + + // parse members + err = parser.parseEnumMembers(section) + if err != nil { return } + + if len(section.members) == 0 { + infoerr.NewError ( + section.location, + "defining an enum with no members", + infoerr.ErrorKindWarn).Print() + } + return +} From c4f763af5b4d78eacf9be4ad56c87126a6470bcb Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sun, 21 Aug 2022 02:48:36 -0400 Subject: [PATCH 3/8] Added test case for enum section --- parser/parser_test.go | 34 ++++++++++++++++++++++++++++++++++ parser/tree.go | 1 + tests/parser/enum/main.arf | 30 ++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 tests/parser/enum/main.arf diff --git a/parser/parser_test.go b/parser/parser_test.go index d433d64..e8d175b 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -158,3 +158,37 @@ objt ro Init:Obj `, test) } +func TestEnum (test *testing.T) { + checkTree ("../tests/parser/enum", +`:arf +--- +enum ro AffrontToGod:{Int 4} + bird0 + 28394 + 9328 + 398 + 9 + bird1 + 23 + 932832 + 398 + 2349 + bird2 + 1 + 2 + 3 + 4 +enum ro NamedColor:U32 + red 0xFF0000 + green 0x00FF00 + blue 0x0000FF +enum ro Weekday:Int + sunday + monday + tuesday + wednesday + thursday + friday + saturday +`, test) +} diff --git a/parser/tree.go b/parser/tree.go index f5cf332..559dbc8 100644 --- a/parser/tree.go +++ b/parser/tree.go @@ -200,5 +200,6 @@ type EnumSection struct { what Type permission types.Permission + // TODO: order matters here we need to store these in an array members map[string] Argument } diff --git a/tests/parser/enum/main.arf b/tests/parser/enum/main.arf new file mode 100644 index 0000000..0571149 --- /dev/null +++ b/tests/parser/enum/main.arf @@ -0,0 +1,30 @@ +:arf +--- + +enum ro Weekday:Int + sunday + monday + tuesday + wednesday + thursday + friday + saturday + +enum ro NamedColor:U32 + red 0xFF0000 + green 0x00FF00 + blue 0x0000FF + +enum ro AffrontToGod:{Int 4} + bird0 + 28394 9328 + 398 9 + bird1 + 23 932832 + 398 + 2349 + bird2 + 1 + 2 + 3 + 4 From 6a6fe8353e7c7e1569ebb95f732c515aaaa3e256 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sun, 21 Aug 2022 11:17:56 -0400 Subject: [PATCH 4/8] Add untested enum parsing --- parser/enum.go | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/parser/enum.go b/parser/enum.go index 0618df8..ca7c822 100644 --- a/parser/enum.go +++ b/parser/enum.go @@ -50,3 +50,43 @@ func (parser *ParsingOperation) parseEnumSection () ( } return } + +// parseEnumMembers parses a list of members for an enum section. Indentation +// level is assumed. +func (parser *ParsingOperation) parseEnumMembers ( + into *EnumSection, +) ( + err error, +) { + + for { + // if we've left the block, stop parsing + if !parser.token.Is(lexer.TokenKindIndent) { return } + if parser.token.Value().(int) != 1 { return } + + // get name + err = parser.nextToken(lexer.TokenKindName) + if err != nil { return } + name := parser.token.Value().(string) + + // parse default value + var argument Argument + if parser.token.Is(lexer.TokenKindNewline) { + err = parser.nextToken() + if err != nil { return } + + argument, err = parser.parseInitializationValues(1) + into.members[name] = argument + if err != nil { return } + } else { + argument, err = parser.parseArgument() + into.members[name] = argument + if err != nil { return } + + err = parser.expect(lexer.TokenKindNewline) + if err != nil { return } + err = parser.nextToken() + if err != nil { return } + } + } +} From d8074fa5cb7a8d0e58482b0a9607f231b8864966 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Tue, 23 Aug 2022 01:30:56 -0400 Subject: [PATCH 5/8] Enum default values are now parsed properly Previously the parser would stay on the member name and parse it the default value. It now moves forward and catches the actual default value. --- parser/enum.go | 2 ++ parser/tree-tostring.go | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/parser/enum.go b/parser/enum.go index ca7c822..139cd9f 100644 --- a/parser/enum.go +++ b/parser/enum.go @@ -68,6 +68,8 @@ func (parser *ParsingOperation) parseEnumMembers ( err = parser.nextToken(lexer.TokenKindName) if err != nil { return } name := parser.token.Value().(string) + err = parser.nextToken() + if err != nil { return } // parse default value var argument Argument diff --git a/parser/tree-tostring.go b/parser/tree-tostring.go index a26c6c9..67eb8ef 100644 --- a/parser/tree-tostring.go +++ b/parser/tree-tostring.go @@ -335,19 +335,19 @@ func (section *EnumSection) ToString (indent int) (output string) { for _, name := range sortMapKeysAlphabetically(section.members) { output += doIndent(indent, name, " ") - member := section.members[name] + defaultValue := section.members[name] isComplexInitialization := - member.kind == ArgumentKindObjectInitializationValues || - member.kind == ArgumentKindArrayInitializationValues + defaultValue.kind == ArgumentKindObjectInitializationValues || + defaultValue.kind == ArgumentKindArrayInitializationValues - if member.value == nil { + if defaultValue.value == nil { output += "\n" } else if isComplexInitialization { output += "\n" - output += member.ToString(indent + 1, true) + output += defaultValue.ToString(indent + 1, true) } else { - output += " " + member.ToString(0, false) + output += " " + defaultValue.ToString(0, false) output += "\n" } } From 5dcf3b3d1abc25922840004c36ff81fdad8a8574 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Tue, 23 Aug 2022 01:33:28 -0400 Subject: [PATCH 6/8] Fixed ToString formatting of enum --- parser/tree-tostring.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parser/tree-tostring.go b/parser/tree-tostring.go index 67eb8ef..8c67798 100644 --- a/parser/tree-tostring.go +++ b/parser/tree-tostring.go @@ -333,7 +333,7 @@ func (section *EnumSection) ToString (indent int) (output string) { section.what.ToString(), "\n") for _, name := range sortMapKeysAlphabetically(section.members) { - output += doIndent(indent, name, " ") + output += doIndent(indent + 1, name) defaultValue := section.members[name] @@ -345,7 +345,7 @@ func (section *EnumSection) ToString (indent int) (output string) { output += "\n" } else if isComplexInitialization { output += "\n" - output += defaultValue.ToString(indent + 1, true) + output += defaultValue.ToString(indent + 2, true) } else { output += " " + defaultValue.ToString(0, false) output += "\n" From aa84d9a4297659cf717fcfc731f11a796d8ed9f4 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Tue, 23 Aug 2022 01:35:35 -0400 Subject: [PATCH 7/8] Removed space alignment and hex literals from test case check ToString is not capable of producing this --- parser/parser_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/parser/parser_test.go b/parser/parser_test.go index e8d175b..42d789f 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -179,9 +179,9 @@ enum ro AffrontToGod:{Int 4} 3 4 enum ro NamedColor:U32 - red 0xFF0000 - green 0x00FF00 - blue 0x0000FF + red 16711680 + green 65280 + blue 255 enum ro Weekday:Int sunday monday From c29efd97baa289016689013dadeafb5976717723 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Tue, 23 Aug 2022 01:36:40 -0400 Subject: [PATCH 8/8] Organized test case members alphabetically --- parser/parser_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/parser/parser_test.go b/parser/parser_test.go index 42d789f..ca4b7a0 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -179,16 +179,16 @@ enum ro AffrontToGod:{Int 4} 3 4 enum ro NamedColor:U32 - red 16711680 - green 65280 blue 255 + green 65280 + red 16711680 enum ro Weekday:Int - sunday + friday monday + saturday + sunday + thursday tuesday wednesday - thursday - friday - saturday `, test) }