Added untested type mismatch error reporting thing
This commit is contained in:
parent
020833c4c6
commit
41724a7e03
@ -15,6 +15,7 @@ type Argument interface {
|
|||||||
// FloatLiteral
|
// FloatLiteral
|
||||||
// StringLiteral
|
// StringLiteral
|
||||||
|
|
||||||
|
What () (what Type)
|
||||||
ToString (indent int) (output string)
|
ToString (indent int) (output string)
|
||||||
canBePassedAs (what Type) (allowed bool)
|
canBePassedAs (what Type) (allowed bool)
|
||||||
}
|
}
|
||||||
|
8
analyzer/common-errors.go
Normal file
8
analyzer/common-errors.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package analyzer
|
||||||
|
|
||||||
|
func typeMismatchErrorMessage (source Type, destination Type) (message string) {
|
||||||
|
message += source.Describe()
|
||||||
|
message += " cannot be used as "
|
||||||
|
message += destination.Describe()
|
||||||
|
return
|
||||||
|
}
|
@ -14,6 +14,13 @@ func (literal IntLiteral) ToString (indent int) (output string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// What returns the type of the argument
|
||||||
|
func (literal IntLiteral) What () (what Type) {
|
||||||
|
what.actual = &PrimitiveI64
|
||||||
|
what.length = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// canBePassedAs returns true if this literal can be implicitly cast to the
|
// canBePassedAs returns true if this literal can be implicitly cast to the
|
||||||
// specified type, and false if it can't.
|
// specified type, and false if it can't.
|
||||||
func (literal IntLiteral) canBePassedAs (what Type) (allowed bool) {
|
func (literal IntLiteral) canBePassedAs (what Type) (allowed bool) {
|
||||||
@ -43,6 +50,13 @@ func (literal UIntLiteral) ToString (indent int) (output string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// What returns the type of the argument
|
||||||
|
func (literal UIntLiteral) What () (what Type) {
|
||||||
|
what.actual = &PrimitiveU64
|
||||||
|
what.length = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// canBePassedAs returns true if this literal can be implicitly cast to the
|
// canBePassedAs returns true if this literal can be implicitly cast to the
|
||||||
// specified type, and false if it can't.
|
// specified type, and false if it can't.
|
||||||
func (literal UIntLiteral) canBePassedAs (what Type) (allowed bool) {
|
func (literal UIntLiteral) canBePassedAs (what Type) (allowed bool) {
|
||||||
@ -71,6 +85,13 @@ func (literal UIntLiteral) canBePassedAs (what Type) (allowed bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// What returns the type of the argument
|
||||||
|
func (literal FloatLiteral) What () (what Type) {
|
||||||
|
what.actual = &PrimitiveF64
|
||||||
|
what.length = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// ToString outputs the data in the argument as a string.
|
// ToString outputs the data in the argument as a string.
|
||||||
func (literal FloatLiteral) ToString (indent int) (output 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, "\n"))
|
||||||
@ -95,6 +116,13 @@ func (literal FloatLiteral) canBePassedAs (what Type) (allowed bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// What returns the type of the argument
|
||||||
|
func (literal StringLiteral) What () (what Type) {
|
||||||
|
what.actual = &BuiltInString
|
||||||
|
what.length = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// ToString outputs the data in the argument as a string.
|
// ToString outputs the data in the argument as a string.
|
||||||
func (literal StringLiteral) ToString (indent int) (output 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, "\"\n"))
|
||||||
|
@ -80,12 +80,16 @@ func (analyzer AnalysisOperation) analyzeTypeSection () (
|
|||||||
outputSection.argument,
|
outputSection.argument,
|
||||||
err = analyzer.analyzeArgument(inputSection.Argument())
|
err = analyzer.analyzeArgument(inputSection.Argument())
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
if !outputSection.argument.canBePassedAs(outputSection.what) {
|
|
||||||
|
|
||||||
|
// type check default value
|
||||||
|
if !outputSection.argument.canBePassedAs(outputSection.what) {
|
||||||
|
err = inputSection.Argument().NewError (
|
||||||
|
typeMismatchErrorMessage (
|
||||||
|
outputSection.argument.What(),
|
||||||
|
outputSection.what),
|
||||||
|
infoerr.ErrorKindError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
// TODO: type check default value. possibly add a method to
|
|
||||||
// Argument that takes in a type and determines whether the
|
|
||||||
// argument can fit to it.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: analyze members
|
// TODO: analyze members
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package analyzer
|
package analyzer
|
||||||
|
|
||||||
// import "git.tebibyte.media/arf/arf/types"
|
import "fmt"
|
||||||
|
import "path/filepath"
|
||||||
import "git.tebibyte.media/arf/arf/parser"
|
import "git.tebibyte.media/arf/arf/parser"
|
||||||
import "git.tebibyte.media/arf/arf/infoerr"
|
import "git.tebibyte.media/arf/arf/infoerr"
|
||||||
|
|
||||||
@ -204,3 +205,63 @@ func (analyzer AnalysisOperation) analyzeType (
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Describe provides a human readable description of the type. The value of this
|
||||||
|
// should not be computationally analyzed.
|
||||||
|
func (what Type) Describe () (description string) {
|
||||||
|
if what.kind == TypeKindBasic {
|
||||||
|
actual := what.actual
|
||||||
|
switch actual {
|
||||||
|
case &PrimitiveF32:
|
||||||
|
description += "F32"
|
||||||
|
case &PrimitiveF64:
|
||||||
|
description += "F64"
|
||||||
|
case &PrimitiveFunc:
|
||||||
|
description += "Func"
|
||||||
|
case &PrimitiveFace:
|
||||||
|
description += "Face"
|
||||||
|
case &PrimitiveObj:
|
||||||
|
description += "Obj"
|
||||||
|
case &PrimitiveU64:
|
||||||
|
description += "U64"
|
||||||
|
case &PrimitiveU32:
|
||||||
|
description += "U32"
|
||||||
|
case &PrimitiveU16:
|
||||||
|
description += "U16"
|
||||||
|
case &PrimitiveU8:
|
||||||
|
description += "U8"
|
||||||
|
case &PrimitiveI64:
|
||||||
|
description += "I64"
|
||||||
|
case &PrimitiveI32:
|
||||||
|
description += "I32"
|
||||||
|
case &PrimitiveI16:
|
||||||
|
description += "I16"
|
||||||
|
case &PrimitiveI8:
|
||||||
|
description += "I8"
|
||||||
|
case &PrimitiveUInt:
|
||||||
|
description += "UInt"
|
||||||
|
case &PrimitiveInt:
|
||||||
|
description += "Int"
|
||||||
|
|
||||||
|
case nil:
|
||||||
|
panic("invalid state: Type.actual is nil")
|
||||||
|
|
||||||
|
default:
|
||||||
|
locator := actual.locator()
|
||||||
|
description +=
|
||||||
|
filepath.Base(locator.modulePath) +
|
||||||
|
"." + locator.name
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
description += "{"
|
||||||
|
description += what.points.Describe()
|
||||||
|
description += "}"
|
||||||
|
}
|
||||||
|
|
||||||
|
if what.length > 0 {
|
||||||
|
description += fmt.Sprint(":", what.length)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user