From da6d587a48261dee49a61faa16d24a64caf1e680 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sat, 20 Aug 2022 02:42:52 -0400 Subject: [PATCH 01/14] Split test cases between blind types and objt types --- parser/parser_test.go | 39 ++++++++++++++++++++++++-------------- tests/parser/objt/main.arf | 21 ++++++++++++++++++++ tests/parser/type/main.arf | 17 ----------------- 3 files changed, 46 insertions(+), 31 deletions(-) create mode 100644 tests/parser/objt/main.arf diff --git a/parser/parser_test.go b/parser/parser_test.go index d628e91..17dde9f 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -115,20 +115,6 @@ func TestType (test *testing.T) { --- type ro Basic:Int type ro BasicInit:Int 6 -type ro Complex:Obj - ro that:Basic - ro this:Basic -type ro ComplexInit:Obj - ro that:BasicInit - ro this:Basic 23 -type ro ComplexWithComplexInit:Obj - ro basic:Basic 87 - ro complex0:Complex - .that 98 - .this 2 - ro complex1:Complex - .that 98902 - .this 235 type ro IntArray:{Int ..} type ro IntArrayInit:{Int 3} 3298 @@ -137,3 +123,28 @@ type ro IntArrayInit:{Int 3} `, test) } +func TestType (test *testing.T) { + checkTree ("../tests/parser/objt", +`:arf +--- +type ro Basic:Obj + ro that:Basic + ro this:Basic +type ro ComplexInit:Obj + ro basic:Int 87 + ro complex0:Bird + .that 98 + .this 2 + ro complex1:Bird + .that 98902 + .this 235 + ro whatever:{Int 3} + 230984 + 849 + 394580 +type ro Init:Obj + ro that:String "hello world" + ro this:Int +`, test) +} + diff --git a/tests/parser/objt/main.arf b/tests/parser/objt/main.arf new file mode 100644 index 0000000..4940494 --- /dev/null +++ b/tests/parser/objt/main.arf @@ -0,0 +1,21 @@ +:arf +--- +type ro Basic:Obj + ro that:Basic + ro this:Basic + +type ro Init:Obj + ro that:String "hello world" + ro this:Int 23 + +type ro ComplexInit:Obj + ro whatever:{Int 3} + 230984 + 849 394580 + ro complex0:Bird + .that 98 + .this 2 + ro complex1:Bird + .that 98902 + .this 235 + ro basic:Int 87 diff --git a/tests/parser/type/main.arf b/tests/parser/type/main.arf index b93fc54..d7feb7e 100644 --- a/tests/parser/type/main.arf +++ b/tests/parser/type/main.arf @@ -8,20 +8,3 @@ 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:Obj - ro complex0:Complex - .that 98 - .this 2 - ro complex1:Complex - .that 98902 - .this 235 - ro basic:Basic 87 From 222c47ced904e9facba4465b64c37a50b02f9ef0 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sat, 20 Aug 2022 02:46:40 -0400 Subject: [PATCH 02/14] Altered tree to separate object and blind type definitions --- parser/tree.go | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/parser/tree.go b/parser/tree.go index 63f885d..d8f502e 100644 --- a/parser/tree.go +++ b/parser/tree.go @@ -161,19 +161,32 @@ type DataSection struct { value Argument } -// TypeNode represents a part of a type. -type TypeNode struct { +// TypeSection represents a blind type definition. +type TypeSection 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 { +// ObjtSection represents an object type definition +type ObjtSection struct { location file.Location - root TypeNode + name string + + what Type + permission types.Permission + children map[string] ObjtMember +} + +// ObjtMember represents a part of an object type definition. +type ObjtMember struct { + location file.Location + name string + + what Type + permission types.Permission + defaultValue Argument } From fc1568aece3cba460bee138314355b24b55eed34 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sat, 20 Aug 2022 12:40:44 -0400 Subject: [PATCH 03/14] Updated ToString methods to match new tree structure --- parser/tree-tostring.go | 77 +++++++++++++++++++++++++++-------------- parser/tree.go | 22 ++++++------ 2 files changed, 62 insertions(+), 37 deletions(-) diff --git a/parser/tree-tostring.go b/parser/tree-tostring.go index 6dcb2ca..fde0ee3 100644 --- a/parser/tree-tostring.go +++ b/parser/tree-tostring.go @@ -253,39 +253,64 @@ func (section *DataSection) ToString (indent int) (output string) { } func (section *TypeSection) ToString (indent int) (output string) { - output += section.root.ToString(indent, true) - return -} + output += doIndent ( + indent, + "type ", + section.permission.ToString(), " ", + section.name, ":", + section.inherits.ToString()) -func (node TypeNode) ToString (indent int, isRoot bool) (output string) { - output += doIndent(indent) - if isRoot { - output += "type " - } - - output += node.permission.ToString() + " " - output += node.name + ":" - output += node.what.ToString() - isComplexInitialization := - node.defaultValue.kind == ArgumentKindObjectInitializationValues || - node.defaultValue.kind == ArgumentKindArrayInitializationValues - - if node.defaultValue.value == nil { + section.defaultValue.kind == ArgumentKindObjectInitializationValues || + section.defaultValue.kind == ArgumentKindArrayInitializationValues + + if section.defaultValue.value == nil { output += "\n" - if len(node.children) > 0 { - for _, name := range sortMapKeysAlphabetically(node.children) { - child := node.children[name] - output += child.ToString(indent + 1, false) - } - } } else if isComplexInitialization { output += "\n" - output += node.defaultValue.ToString(indent + 1, true) + output += section.defaultValue.ToString(indent + 1, true) } else { - output += " " + node.defaultValue.ToString(0, false) - output += "\n" + output += " " + section.defaultValue.ToString(0, false) + output += "\n" + } + return +} + +func (member *ObjtMember) ToString (indent int) (output string) { + output += doIndent(indent) + + output += member.permission.ToString() + " " + output += member.name + ":" + output += member.what.ToString() + + isComplexInitialization := + member.defaultValue.kind == ArgumentKindObjectInitializationValues || + member.defaultValue.kind == ArgumentKindArrayInitializationValues + + if member.defaultValue.value == nil { + output += "\n" + } else if isComplexInitialization { + output += "\n" + output += member.defaultValue.ToString(indent + 1, true) + } else { + output += " " + member.defaultValue.ToString(0, false) + output += "\n" } return } + +func (section *ObjtSection) ToString (indent int) (output string) { + output += doIndent ( + indent, + "objt ", + section.permission.ToString(), " ", + section.name, ":", + section.inherits.ToString(), "\n") + + for _, member := range section.members { + output += member.ToString(indent + 1) + } + return +} + diff --git a/parser/tree.go b/parser/tree.go index d8f502e..a13a7e5 100644 --- a/parser/tree.go +++ b/parser/tree.go @@ -166,21 +166,11 @@ type TypeSection struct { location file.Location name string - what Type + inherits Type permission types.Permission defaultValue Argument } -// ObjtSection represents an object type definition -type ObjtSection struct { - location file.Location - name string - - what Type - permission types.Permission - children map[string] ObjtMember -} - // ObjtMember represents a part of an object type definition. type ObjtMember struct { location file.Location @@ -190,3 +180,13 @@ type ObjtMember struct { permission types.Permission defaultValue Argument } + +// ObjtSection represents an object type definition +type ObjtSection struct { + location file.Location + name string + + inherits Type + permission types.Permission + members map[string] ObjtMember +} From 790e7e632e9aa4967cca476593d3aecbb1376b11 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sat, 20 Aug 2022 12:50:32 -0400 Subject: [PATCH 04/14] Removed recursive member parsing nonsense from type section --- parser/body.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parser/body.go b/parser/body.go index 5def988..3f181d9 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.root.name] = section + parser.tree.typeSections[section.name] = section if err != nil { return } case "face": case "enum": From cb2264977a1570ebf781f91ec8652259bdd6c801 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sat, 20 Aug 2022 13:24:56 -0400 Subject: [PATCH 05/14] Added object sections to the tree for real lol --- parser/body.go | 9 +++++++++ parser/tree.go | 1 + 2 files changed, 10 insertions(+) diff --git a/parser/body.go b/parser/body.go index 3f181d9..da8f75c 100644 --- a/parser/body.go +++ b/parser/body.go @@ -29,6 +29,15 @@ func (parser *ParsingOperation) parseBody () (err error) { } parser.tree.typeSections[section.name] = section if err != nil { return } + case "objt": + var section *ObjtSection + section, err = parser.parseObjtSection() + if parser.tree.typeSections == nil { + parser.tree.typeSections = + make(map[string] *TypeSection) + } + parser.tree.objtSections[section.name] = section + if err != nil { return } case "face": case "enum": case "func": diff --git a/parser/tree.go b/parser/tree.go index a13a7e5..c1b5e74 100644 --- a/parser/tree.go +++ b/parser/tree.go @@ -12,6 +12,7 @@ type SyntaxTree struct { requires []string typeSections map[string] *TypeSection + objtSections map[string] *ObjtSection dataSections map[string] *DataSection } From c847d2187dfa12436c977ed5b24573cc70f71ca7 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sat, 20 Aug 2022 13:25:43 -0400 Subject: [PATCH 06/14] Fixed the object section test --- parser/parser_test.go | 4 ++-- tests/parser/objt/main.arf | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/parser/parser_test.go b/parser/parser_test.go index 17dde9f..9fadd07 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -123,7 +123,7 @@ type ro IntArrayInit:{Int 3} `, test) } -func TestType (test *testing.T) { +func TestObjt (test *testing.T) { checkTree ("../tests/parser/objt", `:arf --- @@ -144,7 +144,7 @@ type ro ComplexInit:Obj 394580 type ro Init:Obj ro that:String "hello world" - ro this:Int + ro this:Int `, test) } diff --git a/tests/parser/objt/main.arf b/tests/parser/objt/main.arf index 4940494..a151314 100644 --- a/tests/parser/objt/main.arf +++ b/tests/parser/objt/main.arf @@ -1,14 +1,14 @@ :arf --- -type ro Basic:Obj +objt ro Basic:Obj ro that:Basic ro this:Basic -type ro Init:Obj +objt ro Init:Obj ro that:String "hello world" ro this:Int 23 -type ro ComplexInit:Obj +objt ro ComplexInit:Obj ro whatever:{Int 3} 230984 849 394580 From bd433fc65ddc7a1db9f1ffb271ce33ca32314732 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sat, 20 Aug 2022 13:26:24 -0400 Subject: [PATCH 07/14] Untested object section parsing --- parser/objt.go | 103 +++++++++++++++++++++++++++++++++++++ parser/type.go | 136 ++++--------------------------------------------- 2 files changed, 114 insertions(+), 125 deletions(-) create mode 100644 parser/objt.go diff --git a/parser/objt.go b/parser/objt.go new file mode 100644 index 0000000..1f70434 --- /dev/null +++ b/parser/objt.go @@ -0,0 +1,103 @@ +package parser + +import "git.tebibyte.media/sashakoshka/arf/types" +import "git.tebibyte.media/sashakoshka/arf/lexer" +import "git.tebibyte.media/sashakoshka/arf/infoerr" + +// parseObjtSection parses an object type definition. This allows for structured +// types to be defined, and for member variables to be added and overridden. +func (parser *ParsingOperation) parseObjtSection () ( + section *ObjtSection, + err error, +) { + err = parser.expect(lexer.TokenKindName) + if err != nil { return } + + section = &ObjtSection { 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) + + // parse 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 } + err = parser.nextToken(lexer.TokenKindNewline) + if err != nil { return } + + // parse members + err = parser.parseObjtMembers(section) + + if len(section.members) == 0 { + infoerr.NewError ( + section.location, + "defining an object with no members", + infoerr.ErrorKindWarn).Print() + } + return +} + +func (parser *ParsingOperation) parseObjtMembers ( + into *ObjtSection, +) ( + 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 permission + err = parser.nextToken(lexer.TokenKindPermission) + if err != nil { return } + member := ObjtMember { } + member.permission = parser.token.Value().(types.Permission) + + // get name + err = parser.nextToken(lexer.TokenKindName) + if err != nil { return } + member.name = parser.token.Value().(string) + + // get type + err = parser.nextToken(lexer.TokenKindColon) + if err != nil { return } + err = parser.nextToken() + if err != nil { return } + member.what, err = parser.parseType() + if err != nil { return } + + // parse default value + if parser.token.Is(lexer.TokenKindNewline) { + err = parser.nextToken() + if err != nil { return } + + member.defaultValue, + err = parser.parseInitializationValues(1) + if err != nil { return } + } else { + member.defaultValue, err = parser.parseArgument() + if err != nil { return } + + err = parser.expect(lexer.TokenKindNewline) + if err != nil { return } + err = parser.nextToken() + if err != nil { return } + } + + // go onto the next line + err = parser.nextToken(lexer.TokenKindNewline) + if err != nil { return } + err = parser.nextToken() + if err != nil { return } + } +} diff --git a/parser/type.go b/parser/type.go index a954396..9691dcf 100644 --- a/parser/type.go +++ b/parser/type.go @@ -2,9 +2,10 @@ 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. +// parseTypeSection parses a blind type definition, meaning it can inherit from +// anything including primitives, but cannot define structure. func (parser *ParsingOperation) parseTypeSection () ( section *TypeSection, err error, @@ -14,50 +15,33 @@ func (parser *ParsingOperation) parseTypeSection () ( section = &TypeSection { location: parser.token.Location() } - // parse root node - err = parser.nextToken() - if err != nil { return } - section.root, err = parser.parseTypeNode(0) - - return -} - -// parseTypeNode parses a single type definition node recursively. -func (parser *ParsingOperation) parseTypeNode ( - baseIndent int, -) ( - node TypeNode, - err error, -) { - node.children = make(map[string] TypeNode) - // get permission - err = parser.expect(lexer.TokenKindPermission) + err = parser.nextToken(lexer.TokenKindPermission) if err != nil { return } - node.permission = parser.token.Value().(types.Permission) + section.permission = parser.token.Value().(types.Permission) // get name err = parser.nextToken(lexer.TokenKindName) if err != nil { return } - node.name = parser.token.Value().(string) + section.name = parser.token.Value().(string) - // get inherited type + // parse inherited type err = parser.nextToken(lexer.TokenKindColon) if err != nil { return } err = parser.nextToken() if err != nil { return } - node.what, err = parser.parseType() + section.inherits, err = parser.parseType() if err != nil { return } - // get value, or child nodes + // parse default values if parser.token.Is(lexer.TokenKindNewline) { err = parser.nextToken() if err != nil { return } - err = parser.parseTypeNodeBlock(baseIndent, &node) + section.defaultValue, err = parser.parseInitializationValues(0) if err != nil { return } } else { - node.defaultValue, err = parser.parseArgument() + section.defaultValue, err = parser.parseArgument() if err != nil { return } err = parser.expect(lexer.TokenKindNewline) @@ -67,101 +51,3 @@ 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 if parser.token.Is(lexer.TokenKindPermission) { - - // child members - parser.previousToken() - err = parser.parseTypeNodeChildren(parent) - - } 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 -} - -// 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) - - // 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 edb9c1a0b6131bd669580e93a031b4ec6cb2e2d5 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sat, 20 Aug 2022 13:29:04 -0400 Subject: [PATCH 08/14] Fixed assignment to entry in nil map --- parser/body.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/parser/body.go b/parser/body.go index da8f75c..82b2635 100644 --- a/parser/body.go +++ b/parser/body.go @@ -32,9 +32,9 @@ func (parser *ParsingOperation) parseBody () (err error) { case "objt": var section *ObjtSection section, err = parser.parseObjtSection() - if parser.tree.typeSections == nil { - parser.tree.typeSections = - make(map[string] *TypeSection) + if parser.tree.objtSections == nil { + parser.tree.objtSections = + make(map[string] *ObjtSection) } parser.tree.objtSections[section.name] = section if err != nil { return } From 0ceaedbcd87c7ae899e62b6b26fdd0b4811e1876 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sat, 20 Aug 2022 13:42:09 -0400 Subject: [PATCH 09/14] Object sections now ToString properly --- parser/tree-tostring.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/parser/tree-tostring.go b/parser/tree-tostring.go index fde0ee3..d469ed3 100644 --- a/parser/tree-tostring.go +++ b/parser/tree-tostring.go @@ -51,6 +51,11 @@ func (tree *SyntaxTree) ToString (indent int) (output string) { output += tree.typeSections[name].ToString(indent) } + objtSectionKeys := sortMapKeysAlphabetically(tree.objtSections) + for _, name := range objtSectionKeys { + output += tree.objtSections[name].ToString(indent) + } + dataSectionKeys := sortMapKeysAlphabetically(tree.dataSections) for _, name := range dataSectionKeys { output += tree.dataSections[name].ToString(indent) @@ -276,7 +281,7 @@ func (section *TypeSection) ToString (indent int) (output string) { return } -func (member *ObjtMember) ToString (indent int) (output string) { +func (member ObjtMember) ToString (indent int) (output string) { output += doIndent(indent) output += member.permission.ToString() + " " @@ -308,8 +313,8 @@ func (section *ObjtSection) ToString (indent int) (output string) { section.name, ":", section.inherits.ToString(), "\n") - for _, member := range section.members { - output += member.ToString(indent + 1) + for _, name := range sortMapKeysAlphabetically(section.members) { + output += section.members[name].ToString(indent + 1) } return } From 617d76fc46831e1ae07ffa2e7bb30dd18dd6d903 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sat, 20 Aug 2022 13:43:10 -0400 Subject: [PATCH 10/14] Object sections now parse properly --- parser/objt.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/parser/objt.go b/parser/objt.go index 1f70434..da7fffe 100644 --- a/parser/objt.go +++ b/parser/objt.go @@ -13,7 +13,10 @@ func (parser *ParsingOperation) parseObjtSection () ( err = parser.expect(lexer.TokenKindName) if err != nil { return } - section = &ObjtSection { location: parser.token.Location() } + section = &ObjtSection { + location: parser.token.Location(), + members: make(map[string] ObjtMember), + } // get permission err = parser.nextToken(lexer.TokenKindPermission) @@ -32,7 +35,9 @@ func (parser *ParsingOperation) parseObjtSection () ( if err != nil { return } section.inherits, err = parser.parseType() if err != nil { return } - err = parser.nextToken(lexer.TokenKindNewline) + err = parser.expect(lexer.TokenKindNewline) + if err != nil { return } + err = parser.nextToken() if err != nil { return } // parse members @@ -94,10 +99,7 @@ func (parser *ParsingOperation) parseObjtMembers ( if err != nil { return } } - // go onto the next line - err = parser.nextToken(lexer.TokenKindNewline) - if err != nil { return } - err = parser.nextToken() - if err != nil { return } + // add member to object section + into.members[member.name] = member } } From 5271876196ba3b6f1565c280dbd6222d82e70ee2 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sat, 20 Aug 2022 13:46:10 -0400 Subject: [PATCH 11/14] Changed data in object test to use objt keyword instead of type --- 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 9fadd07..5d38cc9 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -127,10 +127,10 @@ func TestObjt (test *testing.T) { checkTree ("../tests/parser/objt", `:arf --- -type ro Basic:Obj +objt ro Basic:Obj ro that:Basic ro this:Basic -type ro ComplexInit:Obj +objt ro ComplexInit:Obj ro basic:Int 87 ro complex0:Bird .that 98 @@ -142,7 +142,7 @@ type ro ComplexInit:Obj 230984 849 394580 -type ro Init:Obj +objt ro Init:Obj ro that:String "hello world" ro this:Int `, test) From b878017b817e42c4906c3c96ddcb8d844af40a08 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sat, 20 Aug 2022 15:22:25 -0400 Subject: [PATCH 12/14] The last item of object sections is now saved. --- parser/objt.go | 80 +++++++++++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 33 deletions(-) diff --git a/parser/objt.go b/parser/objt.go index da7fffe..f384cff 100644 --- a/parser/objt.go +++ b/parser/objt.go @@ -42,6 +42,7 @@ func (parser *ParsingOperation) parseObjtSection () ( // parse members err = parser.parseObjtMembers(section) + if err != nil { return } if len(section.members) == 0 { infoerr.NewError ( @@ -52,6 +53,8 @@ func (parser *ParsingOperation) parseObjtSection () ( return } +// parseObjtMembers parses a list of members for an object section. Indentation +// level is assumed. func (parser *ParsingOperation) parseObjtMembers ( into *ObjtSection, ) ( @@ -61,45 +64,56 @@ func (parser *ParsingOperation) parseObjtMembers ( // if we've left the block, stop parsing if !parser.token.Is(lexer.TokenKindIndent) { return } if parser.token.Value().(int) != 1 { return } - - // get permission - err = parser.nextToken(lexer.TokenKindPermission) + + // add member to object section + var member ObjtMember + member, err = parser.parseObjtMember() + into.members[member.name] = member if err != nil { return } - member := ObjtMember { } - member.permission = parser.token.Value().(types.Permission) + } +} - // get name - err = parser.nextToken(lexer.TokenKindName) +// parseObjtMember parses a single member of an object section. Indentation +// level is assumed. +func (parser *ParsingOperation) parseObjtMember () ( + member ObjtMember, + err error, +) { + // get permission + err = parser.nextToken(lexer.TokenKindPermission) + if err != nil { return } + member.permission = parser.token.Value().(types.Permission) + + // get name + err = parser.nextToken(lexer.TokenKindName) + if err != nil { return } + member.name = parser.token.Value().(string) + + // get type + err = parser.nextToken(lexer.TokenKindColon) + if err != nil { return } + err = parser.nextToken() + if err != nil { return } + member.what, err = parser.parseType() + if err != nil { return } + + // parse default value + if parser.token.Is(lexer.TokenKindNewline) { + err = parser.nextToken() if err != nil { return } - member.name = parser.token.Value().(string) - // get type - err = parser.nextToken(lexer.TokenKindColon) + member.defaultValue, + err = parser.parseInitializationValues(1) + if err != nil { return } + } else { + member.defaultValue, err = parser.parseArgument() + if err != nil { return } + + err = parser.expect(lexer.TokenKindNewline) if err != nil { return } err = parser.nextToken() if err != nil { return } - member.what, err = parser.parseType() - if err != nil { return } - - // parse default value - if parser.token.Is(lexer.TokenKindNewline) { - err = parser.nextToken() - if err != nil { return } - - member.defaultValue, - err = parser.parseInitializationValues(1) - if err != nil { return } - } else { - member.defaultValue, err = parser.parseArgument() - if err != nil { return } - - err = parser.expect(lexer.TokenKindNewline) - if err != nil { return } - err = parser.nextToken() - if err != nil { return } - } - - // add member to object section - into.members[member.name] = member } + + return } From 3900bbe7bf0faf265b9d37b54e9dad46c161be2a Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sat, 20 Aug 2022 15:45:01 -0400 Subject: [PATCH 13/14] Parser test cases now print out line numbers --- parser/parser_test.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/parser/parser_test.go b/parser/parser_test.go index 5d38cc9..051e771 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -1,6 +1,7 @@ package parser import "io" +import "strings" import "testing" // import "git.tebibyte.media/sashakoshka/arf/types" @@ -10,9 +11,9 @@ func checkTree (modulePath string, correct string, test *testing.T) { treeRunes := []rune(treeString) test.Log("CORRECT TREE:") - test.Log(correct) + logWithLineNumbers(correct, test) test.Log("WHAT WAS PARSED:") - test.Log(treeString) + logWithLineNumbers(treeString, test) if err != io.EOF && err != nil { test.Log("returned error:") @@ -63,6 +64,15 @@ func checkTree (modulePath string, correct string, test *testing.T) { } } +func logWithLineNumbers (bigString string, test *testing.T) { + lines := strings.Split ( + strings.Replace(bigString, "\t", " ", -1), "\n") + + for index, line := range lines { + test.Logf("%3d | %s", index + 1, line) + } +} + func TestMeta (test *testing.T) { checkTree ("../tests/parser/meta", `:arf From f3b2d11f590984a4240291d91aae838955b2f665 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sat, 20 Aug 2022 15:45:45 -0400 Subject: [PATCH 14/14] I swear its not my code thats wrong its the test No like literally this keeps happening --- 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 051e771..d433d64 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -154,7 +154,7 @@ objt ro ComplexInit:Obj 394580 objt ro Init:Obj ro that:String "hello world" - ro this:Int + ro this:Int 23 `, test) }