Added ToString methods for syntax tree nodes

This commit is contained in:
Sasha Koshka 2022-08-15 14:04:57 -04:00
parent b02ff6cda6
commit d91423863b
6 changed files with 293 additions and 15 deletions

View File

@ -2,5 +2,5 @@ package parser
// parseData parses a data section
func (parser *ParsingOperation) parseData () (err error) {
return
}

View File

@ -2,6 +2,7 @@ package parser
import "reflect"
import "testing"
import "git.tebibyte.media/sashakoshka/arf/types"
func checkTree (modulePath string, correct *SyntaxTree, test *testing.T) {
tree, err := Parse(modulePath)
@ -20,8 +21,23 @@ func checkTree (modulePath string, correct *SyntaxTree, test *testing.T) {
}
}
// quickIdentifier returns a simple identifier of names
func quickIdentifier (trail ...string) (identifier Identifier) {
for _, item := range trail {
identifier.trail = append (
identifier.trail,
Argument {
what: ArgumentKindString,
value: item,
},
)
}
return
}
func TestMeta (test *testing.T) {
checkTree("../tests/parser/meta",&SyntaxTree {
checkTree ("../tests/parser/meta", &SyntaxTree {
license: "GPLv3",
author: "Sasha Koshka",
@ -31,3 +47,69 @@ func TestMeta (test *testing.T) {
},
}, test)
}
func TestData (test *testing.T) {
tree := &SyntaxTree {
dataSections: []DataSection {
DataSection {
name: "integer",
permission: types.PermissionFrom("wr"),
what: Type {
kind: TypeKindBasic,
name: quickIdentifier("Int"),
},
value: []Argument {
Argument {
what: ArgumentKindUInt,
value: 3202,
},
},
},
DataSection {
name: "integerPointer",
permission: types.PermissionFrom("wr"),
what: Type {
kind: TypeKindPointer,
points: &Type {
kind: TypeKindBasic,
name: quickIdentifier("Int"),
},
},
value: []Argument {
Argument {
what: ArgumentKindUInt,
value: 3202,
},
},
},
DataSection {
name: "integerArray16",
permission: types.PermissionFrom("wr"),
what: Type {
kind: TypeKindArray,
points: &Type {
kind: TypeKindBasic,
name: quickIdentifier("Int"),
},
length: Argument {
what: ArgumentKindUInt,
value: 16,
}
},
value: []Argument {
Argument {
what: ArgumentKindUInt,
value: 3202,
},
},
},
},
}
checkTree ("../tests/parser/data", tree, test)
}

179
parser/tree-tostring.go Normal file
View File

@ -0,0 +1,179 @@
package parser
import "fmt"
func doIndent (indent int, input ...string) (output string) {
for index := 0; index < indent; index ++ {
output += "\t"
}
for _, inputSection := range input {
output += inputSection
}
return
}
func (tree *SyntaxTree) ToString (indent int) (output string) {
output += doIndent(indent, ":arf\n")
if tree.author != "" {
output += doIndent(indent, "author \"", tree.author, "\"\n")
}
if tree.license != "" {
output += doIndent(indent, "license \"", tree.license, "\"\n")
}
for _, require := range tree.requires {
output += doIndent(indent, "require \"", require, "\"\n")
}
output += doIndent(indent, "---\n")
for _, require := range tree.dataSections {
output += require.ToString(1)
}
return
}
func (identifier *Identifier) ToString () (output string) {
for index, trailItem := range identifier.trail {
if index > 0 {
output += "."
}
output += trailItem.ToString(0, false)
}
return
}
func (what *Type) ToString () (output string) {
if what.kind == TypeKindBasic {
output += what.name.ToString()
} else {
output += "{"
output += what.points.ToString()
output += "}"
}
if what.mutable {
output += ":mut"
}
return
}
func (declaration *Declaration) ToString () (output string) {
output += declaration.name + ":"
output += declaration.what.ToString()
return
}
func (attribute *ObjectAttribute) ToString (
indent int,
breakLine bool,
) (
output string,
) {
if breakLine {
output += doIndent(indent)
}
output += ", " + attribute.name
if breakLine {
output += "\n" + attribute.value.ToString(indent + 1, true)
} else {
output += " " + attribute.value.ToString(0, false)
}
return
}
func (phrase *Phrase) ToString (indent int, breakLine bool) (output string) {
if breakLine {
output += doIndent (
indent,
"[", phrase.command.ToString(0, false))
output += "\n"
for _, argument := range phrase.arguments {
output += doIndent (
indent,
argument.ToString(indent + 1, true))
}
} else {
output += "[" + phrase.command.ToString(0, false)
for _, argument := range phrase.arguments {
output += " " + argument.ToString(0, false)
}
}
output += "]"
if len(phrase.returnsTo) > 0 {
output += " ->"
for _, returnItem := range phrase.returnsTo {
output += " " + returnItem.ToString(0, false)
}
}
if breakLine {
output += "\n"
}
return
}
func (argument *Argument) ToString (indent int, breakLine bool) (output string) {
if !breakLine { indent = 0 }
switch argument.what {
case ArgumentKindPhrase:
output += doIndent (
indent,
argument.value.(*Phrase).ToString (
indent,
breakLine))
case ArgumentKindObjectAttribute:
output += doIndent (
indent,
argument.value.(*ObjectAttribute).ToString (
indent,
breakLine))
case ArgumentKindIdentifier:
output += doIndent (
indent,
argument.value.(*Identifier).ToString())
case ArgumentKindDeclaration:
output += doIndent (
indent,
argument.value.(*Declaration).ToString())
case ArgumentKindInt, ArgumentKindUInt, ArgumentKindFloat:
output += doIndent(indent, fmt.Sprint(argument.value))
case ArgumentKindString:
output += doIndent (
indent,
"\"" + argument.value.(string) + "\"")
case ArgumentKindRune:
output += doIndent (
indent,
"'" + string(argument.value.(rune)) + "'")
case ArgumentKindOperator:
// TODO
}
return
}
func (section *DataSection) ToString (indent int) (output string) {
output += doIndent (
indent,
"data ",
section.permission.ToString(), " ",
section.name, ":",
section.what.ToString())
return
}

View File

@ -10,7 +10,8 @@ type SyntaxTree struct {
license string
author string
requires []string
requires []string
dataSections []DataSection
}
// Identifier represents a chain of arguments separated by a dot.
@ -41,14 +42,14 @@ type Type struct {
mutable bool
kind TypeKind
// only applicable for arrays. a value of zero means it has an
// only applicable for arrays. a value of nil means it has an
// undefined/dynamic length.
length uint64
length *Argument
// not applicable for pointers.
// only applicable for basic.
name Identifier
// only applicable for pointers.
// not applicable for basic.
points *Type
}
@ -119,6 +120,7 @@ const (
ArgumentKindRune
// + - * / etc...
// this is only used as a phrase command
ArgumentKindOperator
)

View File

@ -27,11 +27,10 @@ data wr nestedObject:Obj
, bird3 9328.21348239
# parsing an object literal
func rr main
---
[let object:Obj
, this 324
, that 2139]
let object:Obj , this 324 , that 2139
# func rr main
# ---
# [let object:Obj
# , this 324
# , that 2139]
#
# let object:Obj , this 324 , that 2139

View File

@ -30,3 +30,19 @@ func PermissionFrom (data string) (permission Permission) {
permission.External = ModeFrom(rune(data[1]))
return
}
func (mode Mode) ToString () (output string) {
switch mode {
case ModeNone: output = "n"
case ModeRead: output = "r"
case ModeWrite: output = "w"
}
return
}
func (permission Permission) ToString () (output string) {
output += permission.Internal.ToString()
output += permission.External.ToString()
return
}