syntax-tree-accessors #2
| @ -11,73 +11,43 @@ func (parser *ParsingOperation) parseBody () (err error) { | ||||
| 		err = parser.expect(lexer.TokenKindName) | ||||
| 		if err != nil { return } | ||||
| 		sectionType := parser.token.Value().(string) | ||||
| 		 | ||||
| 
 | ||||
| 		switch sectionType { | ||||
| 		case "data": | ||||
| 			var section *DataSection | ||||
| 			section, err = parser.parseDataSection() | ||||
| 			if parser.tree.dataSections == nil { | ||||
| 				parser.tree.dataSections = | ||||
| 					make(map[string] *DataSection) | ||||
| 			} | ||||
| 			parser.tree.dataSections[section.name] = section | ||||
| 			parser.tree.sections[section.name] = section | ||||
| 			if err != nil { return } | ||||
| 			section, parseErr := parser.parseDataSection() | ||||
| 			err = parser.tree.addSection(section) | ||||
| 			if err      != nil { return } | ||||
| 			if parseErr != 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 | ||||
| 			parser.tree.sections[section.name] = section | ||||
| 			if err != nil { return } | ||||
| 			section, parseErr := parser.parseTypeSection() | ||||
| 			err = parser.tree.addSection(section) | ||||
| 			if err      != nil { return } | ||||
| 			if parseErr != nil { return } | ||||
| 			 | ||||
| 		case "objt": | ||||
| 			var section *ObjtSection | ||||
| 			section, err = parser.parseObjtSection() | ||||
| 			if parser.tree.objtSections == nil { | ||||
| 				parser.tree.objtSections = | ||||
| 					make(map[string] *ObjtSection) | ||||
| 			} | ||||
| 			parser.tree.objtSections[section.name] = section | ||||
| 			parser.tree.sections[section.name] = section | ||||
| 			if err != nil { return } | ||||
| 			section, parseErr := parser.parseObjtSection() | ||||
| 			err = parser.tree.addSection(section) | ||||
| 			if err      != nil { return } | ||||
| 			if parseErr != nil { return } | ||||
| 			 | ||||
| 		case "face": | ||||
| 			var section *FaceSection | ||||
| 			section, err = parser.parseFaceSection() | ||||
| 			if parser.tree.faceSections == nil { | ||||
| 				parser.tree.faceSections = | ||||
| 					make(map[string] *FaceSection) | ||||
| 			} | ||||
| 			parser.tree.faceSections[section.name] = section | ||||
| 			parser.tree.sections[section.name] = section | ||||
| 			if err != nil { return } | ||||
| 			section, parseErr := parser.parseFaceSection() | ||||
| 			err = parser.tree.addSection(section) | ||||
| 			if err      != nil { return } | ||||
| 			if parseErr != nil { return } | ||||
| 			 | ||||
| 		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 | ||||
| 			parser.tree.sections[section.name] = section | ||||
| 			if err != nil { return } | ||||
| 			section, parseErr := parser.parseEnumSection() | ||||
| 			err = parser.tree.addSection(section) | ||||
| 			if err      != nil { return } | ||||
| 			if parseErr != nil { return } | ||||
| 			 | ||||
| 		case "func": | ||||
| 			var section *FuncSection | ||||
| 			section, err = parser.parseFuncSection() | ||||
| 			if parser.tree.funcSections == nil { | ||||
| 				parser.tree.funcSections = | ||||
| 					make(map[string] *FuncSection) | ||||
| 			} | ||||
| 			parser.tree.funcSections[section.name] = section | ||||
| 			parser.tree.sections[section.name] = section | ||||
| 			if err != nil { return } | ||||
| 			section, parseErr := parser.parseFuncSection() | ||||
| 			err = parser.tree.addSection(section) | ||||
| 			if err      != nil { return } | ||||
| 			if parseErr != nil { return } | ||||
| 			 | ||||
| 		default: | ||||
| 			err = parser.token.NewError ( | ||||
| @ -87,3 +57,18 @@ func (parser *ParsingOperation) parseBody () (err error) { | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // addSection adds a section to the tree, ensuring it has a unique name within | ||||
| // the module. | ||||
| func (tree *SyntaxTree) addSection (section Section) (err error) { | ||||
| 	_, exists := tree.sections[section.Name()] | ||||
| 	if exists { | ||||
| 		err = section.NewError ( | ||||
| 			"cannot have multiple sections with the same name", | ||||
| 			infoerr.ErrorKindError) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	tree.sections[section.Name()] = section | ||||
| 	return | ||||
| } | ||||
|  | ||||
| @ -20,7 +20,7 @@ func (trait locatable) NewError ( | ||||
| 	message string, | ||||
| 	kind    infoerr.ErrorKind, | ||||
| ) ( | ||||
| 	err infoerr.Error, | ||||
| 	err error, | ||||
| ) { | ||||
| 	err = infoerr.NewError(trait.location, message, kind) | ||||
| 	return | ||||
|  | ||||
| @ -20,7 +20,12 @@ type ParsingOperation struct { | ||||
| // Parse reads the files located in the module specified by modulePath, and | ||||
| // converts them into an abstract syntax tree. | ||||
| func Parse (modulePath string) (tree *SyntaxTree, err error) { | ||||
| 	parser := ParsingOperation { modulePath: modulePath } | ||||
| 	parser := ParsingOperation { | ||||
| 		modulePath: modulePath, | ||||
| 		tree: &SyntaxTree { | ||||
| 			sections: make(map[string] Section),			 | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	if parser.modulePath[len(parser.modulePath) - 1] != '/' { | ||||
| 		parser.modulePath += "/" | ||||
| @ -54,9 +59,6 @@ func (parser *ParsingOperation) parse (sourceFile *file.File) (err error) { | ||||
| 	if err != nil { return } | ||||
| 
 | ||||
| 	// reset the parser | ||||
| 	if parser.tree == nil { | ||||
| 		parser.tree = &SyntaxTree { } | ||||
| 	} | ||||
| 	if len(tokens) == 0 { return } | ||||
| 	parser.tokens = tokens | ||||
| 	parser.token  = tokens[0] | ||||
|  | ||||
| @ -47,35 +47,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) | ||||
| 	sectionKeys := sortMapKeysAlphabetically(tree.sections) | ||||
| 	for _, name := range sectionKeys { | ||||
| 		output += tree.sections[name].ToString(indent) | ||||
| 	} | ||||
| 
 | ||||
| 	objtSectionKeys := sortMapKeysAlphabetically(tree.objtSections) | ||||
| 	for _, name := range objtSectionKeys { | ||||
| 		output += tree.objtSections[name].ToString(indent) | ||||
| 	} | ||||
| 
 | ||||
| 	enumSectionKeys := sortMapKeysAlphabetically(tree.enumSections) | ||||
| 	for _, name := range enumSectionKeys { | ||||
| 		output += tree.enumSections[name].ToString(indent) | ||||
| 	} | ||||
| 
 | ||||
| 	faceSectionKeys := sortMapKeysAlphabetically(tree.faceSections) | ||||
| 	for _, name := range faceSectionKeys { | ||||
| 		output += tree.faceSections[name].ToString(indent) | ||||
| 	} | ||||
| 
 | ||||
| 	dataSectionKeys := sortMapKeysAlphabetically(tree.dataSections) | ||||
| 	for _, name := range dataSectionKeys { | ||||
| 		output += tree.dataSections[name].ToString(indent) | ||||
| 	} | ||||
| 
 | ||||
| 	funcSectionKeys := sortMapKeysAlphabetically(tree.funcSections) | ||||
| 	for _, name := range funcSectionKeys { | ||||
| 		output += tree.funcSections[name].ToString(indent) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -2,6 +2,7 @@ package parser | ||||
| 
 | ||||
| import "git.tebibyte.media/arf/arf/file" | ||||
| import "git.tebibyte.media/arf/arf/types" | ||||
| import "git.tebibyte.media/arf/arf/infoerr" | ||||
| 
 | ||||
| // SyntaxTree represents an abstract syntax tree. It covers an entire module. It | ||||
| // can be expected to be syntactically correct, but it might not be semantically | ||||
| @ -12,13 +13,6 @@ type SyntaxTree struct { | ||||
| 
 | ||||
| 	requires []string | ||||
| 	sections map[string] Section | ||||
| 	 | ||||
| 	typeSections map[string] *TypeSection | ||||
| 	objtSections map[string] *ObjtSection | ||||
| 	enumSections map[string] *EnumSection | ||||
| 	faceSections map[string] *FaceSection | ||||
| 	dataSections map[string] *DataSection | ||||
| 	funcSections map[string] *FuncSection | ||||
| } | ||||
| 
 | ||||
| // SectionKind differentiates Section interfaces. | ||||
| @ -40,6 +34,8 @@ type Section interface { | ||||
| 	Kind       () (kind SectionKind) | ||||
| 	Permission () (permission types.Permission) | ||||
| 	Name       () (name string) | ||||
| 	NewError   (message string, kind infoerr.ErrorKind) (err error) | ||||
| 	ToString   (indent int) (output string) | ||||
| } | ||||
| 
 | ||||
| // Identifier represents a chain of arguments separated by a dot. | ||||
|  | ||||
		Reference in New Issue
	
	Block a user