From bc9beb0317162df69368f5683d15107284f6dcbd Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Thu, 18 Aug 2022 16:56:42 -0400 Subject: [PATCH 01/15] Created test case for type section --- parser/parser_test.go | 33 +++++++++++++++++++++++++++++++++ parser/tree.go | 23 ++++++++++++++++++++++- tests/parser/type/main.arf | 27 +++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 tests/parser/type/main.arf diff --git a/parser/parser_test.go b/parser/parser_test.go index 221084f..fb87077 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -109,3 +109,36 @@ data ro object:Obj `, test) } +func TestType (test *testing.T) { + checkTree ("../tests/parser/type", +` +:arf +--- +type ro Basic:Int + +type ro BasicInit:Int 6 + +type ro IntArray:{Int ..} + +type ro IntArrayInit:{Int 3} + 3298 923 92 + +type ro Complex:Obj + ro that:Basic + ro this:Basic + +type ro ComplexInit:Obj + ro that:BasicInit + ro this:Basic 23 + +type ro ComplexWithComplexInit + ro basic:Basic 87 + ro complex0:Complex + .that 98 + .this 2 + ro complex1:Complex + .that 98902 + .this 235 +`, test) +} + diff --git a/parser/tree.go b/parser/tree.go index 9ef87e7..070f36a 100644 --- a/parser/tree.go +++ b/parser/tree.go @@ -156,6 +156,27 @@ type DataSection struct { name string what Type - value Argument permission types.Permission + value Argument +} + +// TypeMember represents member data +type TypeMember struct { + location file.Location + name string + + what Type + permission types.Permission + defaultValue Argument +} + +// TypeSection represents a type definition. +type TypeSection struct { + location file.Location + name string + + what Type + permission types.Permission + // this should be 1 dimensional for now. + members map[string] TypeMember } diff --git a/tests/parser/type/main.arf b/tests/parser/type/main.arf new file mode 100644 index 0000000..b4085bb --- /dev/null +++ b/tests/parser/type/main.arf @@ -0,0 +1,27 @@ +:arf +--- +type ro Basic:Int + +type ro BasicInit:Int 6 + +type ro IntArray:{Int ..} + +type ro IntArrayInit:{Int 3} + 3298 923 92 + +type ro Complex:Obj + ro that:Basic + ro this:Basic + +type ro ComplexInit:Obj + ro that:BasicInit + ro this:Basic 23 + +type ro ComplexWithComplexInit + ro complex0:Complex + .that 98 + .this 2 + ro complex1:Complex + .that 98902 + .this 235 + ro basic:Basic 87 From 5c2a7aeb07847040ff08f46ffdbb139af6e49d68 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Thu, 18 Aug 2022 17:39:19 -0400 Subject: [PATCH 02/15] Created base for type section parsing --- parser/body.go | 8 ++++++++ parser/tree.go | 1 + parser/type.go | 8 ++++++++ 3 files changed, 17 insertions(+) create mode 100644 parser/type.go diff --git a/parser/body.go b/parser/body.go index dfa27f7..3f181d9 100644 --- a/parser/body.go +++ b/parser/body.go @@ -21,6 +21,14 @@ func (parser *ParsingOperation) parseBody () (err error) { parser.tree.dataSections[section.name] = section if err != nil { return } case "type": + var section *TypeSection + section, err = parser.parseTypeSection() + if parser.tree.typeSections == nil { + parser.tree.typeSections = + make(map[string] *TypeSection) + } + parser.tree.typeSections[section.name] = section + if err != nil { return } case "face": case "enum": case "func": diff --git a/parser/tree.go b/parser/tree.go index 070f36a..99b93d3 100644 --- a/parser/tree.go +++ b/parser/tree.go @@ -11,6 +11,7 @@ type SyntaxTree struct { author string requires []string + typeSections map[string] *TypeSection dataSections map[string] *DataSection } diff --git a/parser/type.go b/parser/type.go new file mode 100644 index 0000000..0ba64a2 --- /dev/null +++ b/parser/type.go @@ -0,0 +1,8 @@ +package parser + +func (parser *ParsingOperation) parseTypeSection () ( + section *TypeSection, + err error, +) { + return +} From 9fd3fb126331032fabcacfb2dbb1f4b3a408d45d Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Thu, 18 Aug 2022 17:45:34 -0400 Subject: [PATCH 03/15] Added basic ToString method to TypeSection --- parser/tree-tostring.go | 22 ++++++++++++++++++++++ parser/tree.go | 7 ++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/parser/tree-tostring.go b/parser/tree-tostring.go index 75698ca..a22f964 100644 --- a/parser/tree-tostring.go +++ b/parser/tree-tostring.go @@ -46,6 +46,11 @@ func (tree *SyntaxTree) ToString (indent int) (output string) { output += doIndent(indent, "---\n") + typeSectionKeys := sortMapKeysAlphabetically(tree.typeSections) + for _, name := range typeSectionKeys { + output += tree.typeSections[name].ToString(indent) + } + dataSectionKeys := sortMapKeysAlphabetically(tree.dataSections) for _, name := range dataSectionKeys { output += tree.dataSections[name].ToString(indent) @@ -246,3 +251,20 @@ func (section *DataSection) ToString (indent int) (output string) { } return } + +func (section *TypeSection) ToString (indent int) (output string) { + output += doIndent ( + indent, + "type ", + section.permission.ToString(), " ", + section.name, ":", + section.what.ToString()) + + if section.defaultValue.value == nil { + // TODO: print out members + } else { + output += " " + section.defaultValue.ToString(0, false) + output += "\n" + } + return +} diff --git a/parser/tree.go b/parser/tree.go index 99b93d3..8f409ea 100644 --- a/parser/tree.go +++ b/parser/tree.go @@ -176,8 +176,9 @@ type TypeSection struct { location file.Location name string - what Type - permission types.Permission + what Type + permission types.Permission + defaultValue Argument // this should be 1 dimensional for now. - members map[string] TypeMember + members map[string] TypeMember } From cced825f74427f972629994c1e5ed896c9842ce5 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Thu, 18 Aug 2022 19:40:35 -0400 Subject: [PATCH 04/15] Changed this one thing to the other thing --- parser/tree-tostring.go | 2 +- parser/tree.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/parser/tree-tostring.go b/parser/tree-tostring.go index a22f964..8c40986 100644 --- a/parser/tree-tostring.go +++ b/parser/tree-tostring.go @@ -258,7 +258,7 @@ func (section *TypeSection) ToString (indent int) (output string) { "type ", section.permission.ToString(), " ", section.name, ":", - section.what.ToString()) + section.inherits.ToString()) if section.defaultValue.value == nil { // TODO: print out members diff --git a/parser/tree.go b/parser/tree.go index 8f409ea..30b4be5 100644 --- a/parser/tree.go +++ b/parser/tree.go @@ -176,7 +176,7 @@ type TypeSection struct { location file.Location name string - what Type + inherits Type permission types.Permission defaultValue Argument // this should be 1 dimensional for now. From ef90115a1b98aa6d4ab590d801e3c556a5daf2b4 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Thu, 18 Aug 2022 20:09:04 -0400 Subject: [PATCH 05/15] Fixed some test case formatting --- parser/parser_test.go | 6 ------ parser/tree-tostring.go | 6 +++++- parser/type.go | 42 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/parser/parser_test.go b/parser/parser_test.go index fb87077..571d288 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -115,22 +115,16 @@ func TestType (test *testing.T) { :arf --- type ro Basic:Int - type ro BasicInit:Int 6 - type ro IntArray:{Int ..} - type ro IntArrayInit:{Int 3} 3298 923 92 - type ro Complex:Obj ro that:Basic ro this:Basic - type ro ComplexInit:Obj ro that:BasicInit ro this:Basic 23 - type ro ComplexWithComplexInit ro basic:Basic 87 ro complex0:Complex diff --git a/parser/tree-tostring.go b/parser/tree-tostring.go index 8c40986..894d720 100644 --- a/parser/tree-tostring.go +++ b/parser/tree-tostring.go @@ -261,7 +261,11 @@ func (section *TypeSection) ToString (indent int) (output string) { section.inherits.ToString()) if section.defaultValue.value == nil { - // TODO: print out members + if len(section.members) > 0 { + // TODO: print out members + } else { + output += "\n" + } } else { output += " " + section.defaultValue.ToString(0, false) output += "\n" diff --git a/parser/type.go b/parser/type.go index 0ba64a2..7f1b3f5 100644 --- a/parser/type.go +++ b/parser/type.go @@ -1,8 +1,50 @@ 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) parseTypeSection () ( section *TypeSection, err error, ) { + err = parser.expect(lexer.TokenKindName) + if err != nil { return } + + section = &TypeSection { location: parser.token.Location() } + + // 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) + + // get inherited type + err = parser.nextToken(lexer.TokenKindColon) + if err != nil { return } + err = parser.nextToken() + if err != nil { return } + section.inherits, err = parser.parseType() + if err != nil { return } + + if parser.token.Is(lexer.TokenKindNewline) { + err = parser.nextToken() + if err != nil { return } + + // section.value, err = parser.parseInitializationValues(0) + // if err != nil { return } + } else { + section.defaultValue, err = parser.parseArgument() + if err != nil { return } + + err = parser.expect(lexer.TokenKindNewline) + if err != nil { return } + err = parser.nextToken() + if err != nil { return } + } return } From 717474a59eb9e30fe19dde4ca32c388ec079f0f3 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Thu, 18 Aug 2022 20:09:27 -0400 Subject: [PATCH 06/15] Removed unnescessary println statements (oopsie) --- parser/data.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/parser/data.go b/parser/data.go index a131d24..47c90c4 100644 --- a/parser/data.go +++ b/parser/data.go @@ -94,9 +94,6 @@ func (parser *ParsingOperation) parseObjectInitializationValues () ( initializationValues ObjectInitializationValues, err error, ) { - println("BEGIN") - defer println("END") - initializationValues.attributes = make(map[string] Argument) baseIndent := 0 @@ -116,8 +113,6 @@ func (parser *ParsingOperation) parseObjectInitializationValues () ( // do not parse any further if the indent has changed if indent != baseIndent { break } - println("HIT") - // move on to the beginning of the line, which must contain // a member initialization value err = parser.nextToken(lexer.TokenKindDot) From 69aaae8f14b043dd65163e4c2f0c126e5d4e178a Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Thu, 18 Aug 2022 23:38:32 -0400 Subject: [PATCH 07/15] Restructured type definitions to use a node tree --- parser/body.go | 2 +- parser/tree-tostring.go | 26 +++++++++++++++++--------- parser/tree.go | 13 ++++--------- parser/type.go | 9 +++++---- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/parser/body.go b/parser/body.go index 3f181d9..5def988 100644 --- a/parser/body.go +++ b/parser/body.go @@ -27,7 +27,7 @@ func (parser *ParsingOperation) parseBody () (err error) { parser.tree.typeSections = make(map[string] *TypeSection) } - parser.tree.typeSections[section.name] = section + parser.tree.typeSections[section.root.name] = section if err != nil { return } case "face": case "enum": diff --git a/parser/tree-tostring.go b/parser/tree-tostring.go index 894d720..ebdac69 100644 --- a/parser/tree-tostring.go +++ b/parser/tree-tostring.go @@ -253,22 +253,30 @@ func (section *DataSection) ToString (indent int) (output string) { } func (section *TypeSection) ToString (indent int) (output string) { - output += doIndent ( - indent, - "type ", - section.permission.ToString(), " ", - section.name, ":", - section.inherits.ToString()) + output += section.root.ToString(indent, true) + return +} + +func (node TypeNode) ToString (indent int, isRoot bool) (output string) { + doIndent(indent) + if isRoot { + output += "type " + } - if section.defaultValue.value == nil { - if len(section.members) > 0 { + output += node.permission.ToString() + " " + output += node.name + ":" + output += node.what.ToString() + + if node.defaultValue.value == nil { + if len(node.children) > 0 { // TODO: print out members } else { output += "\n" } } else { - output += " " + section.defaultValue.ToString(0, false) + output += " " + node.defaultValue.ToString(0, false) output += "\n" } + return } diff --git a/parser/tree.go b/parser/tree.go index 30b4be5..63f885d 100644 --- a/parser/tree.go +++ b/parser/tree.go @@ -161,24 +161,19 @@ type DataSection struct { value Argument } -// TypeMember represents member data -type TypeMember struct { +// TypeNode represents a part of a type. +type TypeNode struct { location file.Location name string what Type permission types.Permission defaultValue Argument + children map[string] TypeNode } // TypeSection represents a type definition. type TypeSection struct { location file.Location - name string - - inherits Type - permission types.Permission - defaultValue Argument - // this should be 1 dimensional for now. - members map[string] TypeMember + root TypeNode } diff --git a/parser/type.go b/parser/type.go index 7f1b3f5..bc76c92 100644 --- a/parser/type.go +++ b/parser/type.go @@ -4,6 +4,7 @@ import "git.tebibyte.media/sashakoshka/arf/types" import "git.tebibyte.media/sashakoshka/arf/lexer" // import "git.tebibyte.media/sashakoshka/arf/infoerr" +// parseTypeSection parses a type definition. func (parser *ParsingOperation) parseTypeSection () ( section *TypeSection, err error, @@ -16,19 +17,19 @@ func (parser *ParsingOperation) parseTypeSection () ( // get permission err = parser.nextToken(lexer.TokenKindPermission) if err != nil { return } - section.permission = parser.token.Value().(types.Permission) + section.root.permission = parser.token.Value().(types.Permission) // get name err = parser.nextToken(lexer.TokenKindName) if err != nil { return } - section.name = parser.token.Value().(string) + section.root.name = parser.token.Value().(string) // get inherited type err = parser.nextToken(lexer.TokenKindColon) if err != nil { return } err = parser.nextToken() if err != nil { return } - section.inherits, err = parser.parseType() + section.root.what, err = parser.parseType() if err != nil { return } if parser.token.Is(lexer.TokenKindNewline) { @@ -38,7 +39,7 @@ func (parser *ParsingOperation) parseTypeSection () ( // section.value, err = parser.parseInitializationValues(0) // if err != nil { return } } else { - section.defaultValue, err = parser.parseArgument() + section.root.defaultValue, err = parser.parseArgument() if err != nil { return } err = parser.expect(lexer.TokenKindNewline) From 63419165dd809228a45875ed37a9db567b701bad Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Fri, 19 Aug 2022 02:08:18 -0400 Subject: [PATCH 08/15] Moved most of type section parsing into reusable type node parsing method --- parser/type.go | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/parser/type.go b/parser/type.go index bc76c92..03ef8f1 100644 --- a/parser/type.go +++ b/parser/type.go @@ -14,24 +14,52 @@ func (parser *ParsingOperation) parseTypeSection () ( section = &TypeSection { location: parser.token.Location() } - // get permission - err = parser.nextToken(lexer.TokenKindPermission) + // parse root node + err = parser.nextToken() if err != nil { return } - section.root.permission = parser.token.Value().(types.Permission) + section.root, err = parser.parseTypeNode(true) + + return +} + +func (parser *ParsingOperation) parseTypeNode ( + isRoot bool, +) ( + node TypeNode, + err error, +) { + node.children = make(map[string] TypeNode) + + // determine the indent level of this type node. if this is the root + // node, assume the indent level is zero. + baseIndent := 0 + if !isRoot { + err = parser.expect(lexer.TokenKindIndent) + if err != nil { return } + baseIndent = parser.token.Value().(int) + err = parser.nextToken() + if err != nil { return } + } + + // get permission + err = parser.expect(lexer.TokenKindPermission) + if err != nil { return } + node.permission = parser.token.Value().(types.Permission) // get name err = parser.nextToken(lexer.TokenKindName) if err != nil { return } - section.root.name = parser.token.Value().(string) + node.name = parser.token.Value().(string) // get inherited type err = parser.nextToken(lexer.TokenKindColon) if err != nil { return } err = parser.nextToken() if err != nil { return } - section.root.what, err = parser.parseType() + node.what, err = parser.parseType() if err != nil { return } + // get value, or child nodes if parser.token.Is(lexer.TokenKindNewline) { err = parser.nextToken() if err != nil { return } @@ -39,7 +67,7 @@ func (parser *ParsingOperation) parseTypeSection () ( // section.value, err = parser.parseInitializationValues(0) // if err != nil { return } } else { - section.root.defaultValue, err = parser.parseArgument() + node.defaultValue, err = parser.parseArgument() if err != nil { return } err = parser.expect(lexer.TokenKindNewline) From e25e7bdf140018c252dfecc96d64dbfe526ff1ef Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Fri, 19 Aug 2022 02:34:17 -0400 Subject: [PATCH 09/15] Parser can now parse array and object initializations --- parser/type.go | 53 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/parser/type.go b/parser/type.go index 03ef8f1..b40521d 100644 --- a/parser/type.go +++ b/parser/type.go @@ -22,6 +22,9 @@ func (parser *ParsingOperation) parseTypeSection () ( return } +// parseTypeNode parses a single type definition node recursively. If isRoot is +// true, the parser will assume the current node is the root node of a type +// section and will not search for an indent. func (parser *ParsingOperation) parseTypeNode ( isRoot bool, ) ( @@ -64,8 +67,8 @@ func (parser *ParsingOperation) parseTypeNode ( err = parser.nextToken() if err != nil { return } - // section.value, err = parser.parseInitializationValues(0) - // if err != nil { return } + err = parser.parseTypeNodeBlock(baseIndent, &node) + if err != nil { return } } else { node.defaultValue, err = parser.parseArgument() if err != nil { return } @@ -77,3 +80,49 @@ func (parser *ParsingOperation) parseTypeNode ( } return } + +// parseTypeNodeBlock starts on the line after a type node, and parses what +// could be either an array initialization, an object initialization, or more +// child nodes. It is similar to parseInitializationValues. If none of these +// things were found the parser stays at the beginning of the line and the +// method returns. +func (parser *ParsingOperation) parseTypeNodeBlock ( + baseIndent int, + parent *TypeNode, +) ( + err error, +) { + // check if line is indented one more than baseIndent + if !parser.token.Is(lexer.TokenKindIndent) { return } + if parser.token.Value().(int) != baseIndent + 1 { return } + + thingLocation := parser.token.Location() + + err = parser.nextToken() + if err != nil { return } + + if parser.token.Is(lexer.TokenKindDot) { + + // object initialization + parser.previousToken() + initializationArgument := Argument { location: thingLocation } + var initializationValues ObjectInitializationValues + initializationValues, err = parser.parseObjectInitializationValues() + initializationArgument.kind = ArgumentKindObjectInitializationValues + initializationArgument.value = &initializationValues + parent.defaultValue = initializationArgument + + } else { + + // array initialization + parser.previousToken() + initializationArgument := Argument { location: thingLocation } + var initializationValues ArrayInitializationValues + initializationValues, err = parser.parseArrayInitializationValues() + initializationArgument.kind = ArgumentKindArrayInitializationValues + initializationArgument.value = &initializationValues + parent.defaultValue = initializationArgument + } + + return +} From 19d0b3f45530f7689ae33d5587d5a25275992785 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Fri, 19 Aug 2022 02:36:56 -0400 Subject: [PATCH 10/15] Complex default values of type nodes now ToString properly --- parser/tree-tostring.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/parser/tree-tostring.go b/parser/tree-tostring.go index ebdac69..4ce2df8 100644 --- a/parser/tree-tostring.go +++ b/parser/tree-tostring.go @@ -267,12 +267,19 @@ func (node TypeNode) ToString (indent int, isRoot bool) (output string) { output += node.name + ":" output += node.what.ToString() + isComplexInitialization := + node.defaultValue.kind == ArgumentKindObjectInitializationValues || + node.defaultValue.kind == ArgumentKindArrayInitializationValues + if node.defaultValue.value == nil { if len(node.children) > 0 { // TODO: print out members } else { output += "\n" } + } else if isComplexInitialization { + output += "\n" + output += node.defaultValue.ToString(indent + 1, true) } else { output += " " + node.defaultValue.ToString(0, false) output += "\n" From 2296765e81676d1f605f8f243aacf84bf213eb2c Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Fri, 19 Aug 2022 03:01:47 -0400 Subject: [PATCH 11/15] Added recursive parsing of type nodes --- parser/type.go | 73 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 17 deletions(-) diff --git a/parser/type.go b/parser/type.go index b40521d..cb7e58b 100644 --- a/parser/type.go +++ b/parser/type.go @@ -2,7 +2,7 @@ package parser import "git.tebibyte.media/sashakoshka/arf/types" import "git.tebibyte.media/sashakoshka/arf/lexer" -// import "git.tebibyte.media/sashakoshka/arf/infoerr" +import "git.tebibyte.media/sashakoshka/arf/infoerr" // parseTypeSection parses a type definition. func (parser *ParsingOperation) parseTypeSection () ( @@ -17,33 +17,20 @@ func (parser *ParsingOperation) parseTypeSection () ( // parse root node err = parser.nextToken() if err != nil { return } - section.root, err = parser.parseTypeNode(true) + section.root, err = parser.parseTypeNode(0) return } -// parseTypeNode parses a single type definition node recursively. If isRoot is -// true, the parser will assume the current node is the root node of a type -// section and will not search for an indent. +// parseTypeNode parses a single type definition node recursively. func (parser *ParsingOperation) parseTypeNode ( - isRoot bool, + baseIndent int, ) ( node TypeNode, err error, ) { node.children = make(map[string] TypeNode) - // determine the indent level of this type node. if this is the root - // node, assume the indent level is zero. - baseIndent := 0 - if !isRoot { - err = parser.expect(lexer.TokenKindIndent) - if err != nil { return } - baseIndent = parser.token.Value().(int) - err = parser.nextToken() - if err != nil { return } - } - // get permission err = parser.expect(lexer.TokenKindPermission) if err != nil { return } @@ -112,6 +99,12 @@ func (parser *ParsingOperation) parseTypeNodeBlock ( initializationArgument.value = &initializationValues parent.defaultValue = initializationArgument + } else if parser.token.Is(lexer.TokenKindPermission) { + + // child members + parser.previousToken() + err = parser.parseTypeNodeChildren(parent) + } else { // array initialization @@ -126,3 +119,49 @@ func (parser *ParsingOperation) parseTypeNodeBlock ( return } + +// parseTypeNodeChildren parses child type nodes into a parent type node. +func (parser *ParsingOperation) parseTypeNodeChildren ( + parent *TypeNode, +) ( + err error, +) { + baseIndent := 0 + begin := true + + for { + // if there is no indent we can just stop parsing + if !parser.token.Is(lexer.TokenKindIndent) { break } + indent := parser.token.Value().(int) + + if begin == true { + baseIndent = indent + begin = false + } + + // do not parse any further if the indent has changed + if indent != baseIndent { break } + + // move on to the beginning of the line, which must contain + // a type node + err = parser.nextToken() + if err != nil { return } + var child TypeNode + child, err = parser.parseTypeNode(baseIndent + 1) + + // if the member has already been listed, throw an error + _, exists := parent.children[child.name] + if exists { + err = parser.token.NewError ( + "duplicate member \"" + child.name + + "\" in object member initialization", + infoerr.ErrorKindError) + return + } + + // store in parent + parent.children[child.name] = child + } + + return +} From 9b4279c052ea57c6c84de54929d7d81f2bfcd07e Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Fri, 19 Aug 2022 03:03:36 -0400 Subject: [PATCH 12/15] Fixed ToString of type nodes --- parser/tree-tostring.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/parser/tree-tostring.go b/parser/tree-tostring.go index 4ce2df8..6dcb2ca 100644 --- a/parser/tree-tostring.go +++ b/parser/tree-tostring.go @@ -258,7 +258,7 @@ func (section *TypeSection) ToString (indent int) (output string) { } func (node TypeNode) ToString (indent int, isRoot bool) (output string) { - doIndent(indent) + output += doIndent(indent) if isRoot { output += "type " } @@ -272,10 +272,12 @@ func (node TypeNode) ToString (indent int, isRoot bool) (output string) { node.defaultValue.kind == ArgumentKindArrayInitializationValues if node.defaultValue.value == nil { + output += "\n" if len(node.children) > 0 { - // TODO: print out members - } else { - output += "\n" + for _, name := range sortMapKeysAlphabetically(node.children) { + child := node.children[name] + output += child.ToString(indent + 1, false) + } } } else if isComplexInitialization { output += "\n" From 9dce9b2f758d8e2384eb04ab5c3accc13af22b68 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Fri, 19 Aug 2022 03:05:25 -0400 Subject: [PATCH 13/15] Fixed test formatting --- parser/parser_test.go | 8 +++++--- tests/parser/type/main.arf | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/parser/parser_test.go b/parser/parser_test.go index 571d288..855dcad 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -116,9 +116,6 @@ func TestType (test *testing.T) { --- type ro Basic:Int type ro BasicInit:Int 6 -type ro IntArray:{Int ..} -type ro IntArrayInit:{Int 3} - 3298 923 92 type ro Complex:Obj ro that:Basic ro this:Basic @@ -133,6 +130,11 @@ type ro ComplexWithComplexInit ro complex1:Complex .that 98902 .this 235 +type ro IntArray:{Int ..} +type ro IntArrayInit:{Int 3} + 3298 + 923 + 92 `, test) } diff --git a/tests/parser/type/main.arf b/tests/parser/type/main.arf index b4085bb..b93fc54 100644 --- a/tests/parser/type/main.arf +++ b/tests/parser/type/main.arf @@ -17,7 +17,7 @@ type ro ComplexInit:Obj ro that:BasicInit ro this:Basic 23 -type ro ComplexWithComplexInit +type ro ComplexWithComplexInit:Obj ro complex0:Complex .that 98 .this 2 From 2605d1fb0909db30bb619589f416c0d69571916e Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Fri, 19 Aug 2022 11:36:30 -0400 Subject: [PATCH 14/15] Fixed nested complex initialization values not parsing --- parser/parser_test.go | 3 +-- parser/type.go | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/parser/parser_test.go b/parser/parser_test.go index 855dcad..f324b6e 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -111,8 +111,7 @@ data ro object:Obj func TestType (test *testing.T) { checkTree ("../tests/parser/type", -` -:arf +`:arf --- type ro Basic:Int type ro BasicInit:Int 6 diff --git a/parser/type.go b/parser/type.go index cb7e58b..a954396 100644 --- a/parser/type.go +++ b/parser/type.go @@ -147,7 +147,7 @@ func (parser *ParsingOperation) parseTypeNodeChildren ( err = parser.nextToken() if err != nil { return } var child TypeNode - child, err = parser.parseTypeNode(baseIndent + 1) + child, err = parser.parseTypeNode(baseIndent) // if the member has already been listed, throw an error _, exists := parent.children[child.name] From 78b8b9dacda03baaac1cf0aba02b8fa39442c187 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Fri, 19 Aug 2022 11:37:30 -0400 Subject: [PATCH 15/15] Fixed test case for parser The correct output string was missing a type specifier. The lexer now passes this test. --- parser/parser_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parser/parser_test.go b/parser/parser_test.go index f324b6e..d628e91 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -121,7 +121,7 @@ type ro Complex:Obj type ro ComplexInit:Obj ro that:BasicInit ro this:Basic 23 -type ro ComplexWithComplexInit +type ro ComplexWithComplexInit:Obj ro basic:Basic 87 ro complex0:Complex .that 98