Added a locatable node trait
This commit is contained in:
parent
cd670d05c5
commit
7581541ff5
@ -3,7 +3,6 @@ package analyzer
|
||||
import "os"
|
||||
import "fmt"
|
||||
import "path/filepath"
|
||||
import "git.tebibyte.media/arf/arf/file"
|
||||
import "git.tebibyte.media/arf/arf/parser"
|
||||
import "git.tebibyte.media/arf/arf/infoerr"
|
||||
|
||||
@ -217,15 +216,13 @@ func (analyzer *AnalysisOperation) addSection (section Section) {
|
||||
// destination. If it can, it retunrs nil. If it can't, it returns an error
|
||||
// explaining why.
|
||||
func (analyzer *AnalysisOperation) typeCheck (
|
||||
location file.Location,
|
||||
source Argument,
|
||||
destination Type,
|
||||
) (
|
||||
err error,
|
||||
) {
|
||||
if !source.canBePassedAs(destination) {
|
||||
err = infoerr.NewError (
|
||||
location,
|
||||
err = source.NewError (
|
||||
typeMismatchErrorMessage (
|
||||
source.What(),
|
||||
destination),
|
||||
|
@ -1,7 +1,8 @@
|
||||
package analyzer
|
||||
|
||||
import "git.tebibyte.media/arf/arf/file"
|
||||
import "git.tebibyte.media/arf/arf/parser"
|
||||
// import "git.tebibyte.media/arf/arf/infoerr"
|
||||
import "git.tebibyte.media/arf/arf/infoerr"
|
||||
|
||||
// Argument represents a value that can be placed anywhere a value goes. This
|
||||
// allows things like phrases being arguments to other phrases.
|
||||
@ -16,6 +17,8 @@ type Argument interface {
|
||||
// StringLiteral
|
||||
|
||||
What () (what Type)
|
||||
Location () (location file.Location)
|
||||
NewError (message string, kind infoerr.ErrorKind) (err error)
|
||||
ToString (indent int) (output string)
|
||||
canBePassedAs (what Type) (allowed bool)
|
||||
}
|
||||
@ -76,16 +79,36 @@ func (analyzer AnalysisOperation) analyzeArgument (
|
||||
// TODO
|
||||
|
||||
case parser.ArgumentKindInt:
|
||||
outputArgument = IntLiteral(inputArgument.Value().(int64))
|
||||
outputArgument = IntLiteral {
|
||||
value: inputArgument.Value().(int64),
|
||||
locatable: locatable {
|
||||
location: inputArgument.Location(),
|
||||
},
|
||||
}
|
||||
|
||||
case parser.ArgumentKindUInt:
|
||||
outputArgument = UIntLiteral(inputArgument.Value().(uint64))
|
||||
outputArgument = UIntLiteral {
|
||||
value: inputArgument.Value().(uint64),
|
||||
locatable: locatable {
|
||||
location: inputArgument.Location(),
|
||||
},
|
||||
}
|
||||
|
||||
case parser.ArgumentKindFloat:
|
||||
outputArgument = FloatLiteral(inputArgument.Value().(float64))
|
||||
outputArgument = FloatLiteral {
|
||||
value: inputArgument.Value().(float64),
|
||||
locatable: locatable {
|
||||
location: inputArgument.Location(),
|
||||
},
|
||||
}
|
||||
|
||||
case parser.ArgumentKindString:
|
||||
outputArgument = StringLiteral(inputArgument.Value().(string))
|
||||
outputArgument = StringLiteral {
|
||||
value: inputArgument.Value().(string),
|
||||
locatable: locatable {
|
||||
location: inputArgument.Location(),
|
||||
},
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -2,15 +2,34 @@ package analyzer
|
||||
|
||||
import "fmt"
|
||||
|
||||
type IntLiteral int64
|
||||
type UIntLiteral uint64
|
||||
type FloatLiteral float64
|
||||
type StringLiteral string
|
||||
type RuneLiteral rune
|
||||
type IntLiteral struct {
|
||||
locatable
|
||||
value int64
|
||||
}
|
||||
|
||||
type UIntLiteral struct {
|
||||
locatable
|
||||
value uint64
|
||||
}
|
||||
|
||||
type FloatLiteral struct {
|
||||
locatable
|
||||
value float64
|
||||
}
|
||||
|
||||
type StringLiteral struct {
|
||||
locatable
|
||||
value string
|
||||
}
|
||||
|
||||
type RuneLiteral struct {
|
||||
locatable
|
||||
value rune
|
||||
}
|
||||
|
||||
// ToString outputs the data in the argument as a string.
|
||||
func (literal IntLiteral) ToString (indent int) (output string) {
|
||||
output += doIndent(indent, fmt.Sprint("arg int ", literal, "\n"))
|
||||
output += doIndent(indent, fmt.Sprint("arg int ", literal.value, "\n"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -46,7 +65,7 @@ func (literal IntLiteral) canBePassedAs (what Type) (allowed bool) {
|
||||
|
||||
// ToString outputs the data in the argument as a string.
|
||||
func (literal UIntLiteral) ToString (indent int) (output string) {
|
||||
output += doIndent(indent, fmt.Sprint("arg uint ", literal, "\n"))
|
||||
output += doIndent(indent, fmt.Sprint("arg uint ", literal.value, "\n"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -94,7 +113,7 @@ func (literal FloatLiteral) What () (what Type) {
|
||||
|
||||
// ToString outputs the data in the argument as a string.
|
||||
func (literal FloatLiteral) ToString (indent int) (output string) {
|
||||
output += doIndent(indent, fmt.Sprint("arg float ", literal, "\n"))
|
||||
output += doIndent(indent, fmt.Sprint("arg float ", literal.value, "\n"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -125,7 +144,7 @@ func (literal StringLiteral) What () (what Type) {
|
||||
|
||||
// ToString outputs the data in the argument as a string.
|
||||
func (literal StringLiteral) ToString (indent int) (output string) {
|
||||
output += doIndent(indent, fmt.Sprint("arg string \"", literal, "\"\n"))
|
||||
output += doIndent(indent, fmt.Sprint("arg string '", literal.value, "'\n"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -170,7 +189,7 @@ func (literal StringLiteral) canBePassedAs (what Type) (allowed bool) {
|
||||
|
||||
// ToString outputs the data in the argument as a string.
|
||||
func (literal RuneLiteral) ToString (indent int) (output string) {
|
||||
output += doIndent(indent, fmt.Sprint("arg rune '", literal, "'\n"))
|
||||
output += doIndent(indent, fmt.Sprint("arg rune '", literal.value, "'\n"))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,38 @@
|
||||
package analyzer
|
||||
|
||||
import "path/filepath"
|
||||
import "git.tebibyte.media/arf/arf/file"
|
||||
import "git.tebibyte.media/arf/arf/types"
|
||||
import "git.tebibyte.media/arf/arf/infoerr"
|
||||
|
||||
// locatable allows a tree node to have a location.
|
||||
type locatable struct {
|
||||
location file.Location
|
||||
}
|
||||
|
||||
// Location returns the location of the node.
|
||||
func (node locatable) Location () (location file.Location) {
|
||||
location = node.location
|
||||
return
|
||||
}
|
||||
|
||||
// NewError creates a new error at the node's location.
|
||||
func (node locatable) NewError (
|
||||
message string,
|
||||
kind infoerr.ErrorKind,
|
||||
) (
|
||||
err error,
|
||||
) {
|
||||
err = infoerr.NewError(node.location, message, kind)
|
||||
return
|
||||
}
|
||||
|
||||
// sectionBase is a struct that all sections must embed.
|
||||
type sectionBase struct {
|
||||
where locator
|
||||
complete bool
|
||||
permission types.Permission
|
||||
locatable
|
||||
}
|
||||
|
||||
// Name returns the name of the section.
|
||||
|
@ -3,7 +3,9 @@ package analyzer
|
||||
import "os"
|
||||
import "sort"
|
||||
import "path/filepath"
|
||||
import "git.tebibyte.media/arf/arf/file"
|
||||
import "git.tebibyte.media/arf/arf/types"
|
||||
import "git.tebibyte.media/arf/arf/infoerr"
|
||||
|
||||
// locator uniquely identifies a section in the section table.
|
||||
type locator struct {
|
||||
@ -79,6 +81,8 @@ type Section interface {
|
||||
ModulePath () (path string)
|
||||
ModuleName () (path string)
|
||||
Permission () (permission types.Permission)
|
||||
Location () (location file.Location)
|
||||
NewError (message string, kind infoerr.ErrorKind) (err error)
|
||||
locator () (where locator)
|
||||
|
||||
// Must be implemented by each individual section
|
||||
|
@ -64,6 +64,8 @@ func (analyzer AnalysisOperation) analyzeTypeSection () (
|
||||
analyzer.addSection(section)
|
||||
|
||||
inputSection := analyzer.currentSection.(parser.TypeSection)
|
||||
outputSection.location = analyzer.currentSection.Location()
|
||||
|
||||
if inputSection.Permission() == types.PermissionReadWrite {
|
||||
err = inputSection.NewError (
|
||||
"read-write (rw) permission not understood in this " +
|
||||
@ -83,7 +85,6 @@ func (analyzer AnalysisOperation) analyzeTypeSection () (
|
||||
|
||||
// type check default value
|
||||
err = analyzer.typeCheck (
|
||||
inputSection.Argument().Location(),
|
||||
outputSection.argument,
|
||||
outputSection.what)
|
||||
if err != nil { return }
|
||||
|
@ -21,6 +21,8 @@ const (
|
||||
// Type represents a description of a type. It must eventually point to a
|
||||
// TypeSection.
|
||||
type Type struct {
|
||||
locatable
|
||||
|
||||
// one of these must be nil.
|
||||
actual *TypeSection
|
||||
points *Type
|
||||
@ -170,6 +172,7 @@ func (analyzer AnalysisOperation) analyzeType (
|
||||
) {
|
||||
outputType.mutable = inputType.Mutable()
|
||||
outputType.length = inputType.Length()
|
||||
outputType.location = inputType.Location()
|
||||
if outputType.length < 1 {
|
||||
err = inputType.NewError (
|
||||
"cannot specify a length of zero",
|
||||
|
Reference in New Issue
Block a user