Added untested type mismatch error reporting thing

This commit is contained in:
Sasha Koshka 2022-10-11 17:03:19 -04:00
parent 020833c4c6
commit 41724a7e03
5 changed files with 107 additions and 5 deletions

View File

@ -15,6 +15,7 @@ type Argument interface {
// FloatLiteral
// StringLiteral
What () (what Type)
ToString (indent int) (output string)
canBePassedAs (what Type) (allowed bool)
}

View 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
}

View File

@ -14,6 +14,13 @@ func (literal IntLiteral) ToString (indent int) (output string) {
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
// specified type, and false if it can't.
func (literal IntLiteral) canBePassedAs (what Type) (allowed bool) {
@ -43,6 +50,13 @@ func (literal UIntLiteral) ToString (indent int) (output string) {
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
// specified type, and false if it can't.
func (literal UIntLiteral) canBePassedAs (what Type) (allowed bool) {
@ -71,6 +85,13 @@ func (literal UIntLiteral) canBePassedAs (what Type) (allowed bool) {
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.
func (literal FloatLiteral) ToString (indent int) (output string) {
output += doIndent(indent, fmt.Sprint("arg float ", literal, "\n"))
@ -95,6 +116,13 @@ func (literal FloatLiteral) canBePassedAs (what Type) (allowed bool) {
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.
func (literal StringLiteral) ToString (indent int) (output string) {
output += doIndent(indent, fmt.Sprint("arg string \"", literal, "\"\n"))

View File

@ -80,12 +80,16 @@ func (analyzer AnalysisOperation) analyzeTypeSection () (
outputSection.argument,
err = analyzer.analyzeArgument(inputSection.Argument())
if err != nil { return }
// 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

View File

@ -1,6 +1,7 @@
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/infoerr"
@ -204,3 +205,63 @@ func (analyzer AnalysisOperation) analyzeType (
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
}