Added some useful type checking thigns to literals
This commit is contained in:
parent
e2947eab8c
commit
5c286cf955
@ -19,6 +19,7 @@ type Argument interface {
|
|||||||
// RuneLiteral
|
// RuneLiteral
|
||||||
|
|
||||||
ToString (indent int) (output string)
|
ToString (indent int) (output string)
|
||||||
|
canBePassedAs (what Type) (allowed bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// analyzeArgument analyzes an argument
|
// analyzeArgument analyzes an argument
|
||||||
|
|||||||
@ -14,24 +14,118 @@ func (literal IntLiteral) ToString (indent int) (output string) {
|
|||||||
return
|
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) {
|
||||||
|
// must be a singlular value
|
||||||
|
if what.length != 1 { return }
|
||||||
|
|
||||||
|
// can be passed to types that are signed numbers at a primitive level.
|
||||||
|
primitive := what.underlyingPrimitive()
|
||||||
|
switch primitive {
|
||||||
|
case
|
||||||
|
&PrimitiveF64,
|
||||||
|
&PrimitiveF32,
|
||||||
|
&PrimitiveI64,
|
||||||
|
&PrimitiveI32,
|
||||||
|
&PrimitiveI16,
|
||||||
|
&PrimitiveI8,
|
||||||
|
&PrimitiveInt:
|
||||||
|
|
||||||
|
allowed = true
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// ToString outputs the data in the argument as a string.
|
// ToString outputs the data in the argument as a string.
|
||||||
func (literal UIntLiteral) ToString (indent int) (output 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, "\n"))
|
||||||
return
|
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) {
|
||||||
|
// must be a singlular value
|
||||||
|
if what.length != 1 { return }
|
||||||
|
|
||||||
|
// can be passed to types that are numbers at a primitive level.
|
||||||
|
primitive := what.underlyingPrimitive()
|
||||||
|
switch primitive {
|
||||||
|
case
|
||||||
|
&PrimitiveF64,
|
||||||
|
&PrimitiveF32,
|
||||||
|
&PrimitiveI64,
|
||||||
|
&PrimitiveI32,
|
||||||
|
&PrimitiveI16,
|
||||||
|
&PrimitiveI8,
|
||||||
|
&PrimitiveInt,
|
||||||
|
&PrimitiveU64,
|
||||||
|
&PrimitiveU32,
|
||||||
|
&PrimitiveU16,
|
||||||
|
&PrimitiveU8,
|
||||||
|
&PrimitiveUInt:
|
||||||
|
|
||||||
|
allowed = true
|
||||||
|
}
|
||||||
|
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"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// canBePassedAs returns true if this literal can be implicitly cast to the
|
||||||
|
// specified type, and false if it can't.
|
||||||
|
func (literal FloatLiteral) canBePassedAs (what Type) (allowed bool) {
|
||||||
|
// must be a singlular value
|
||||||
|
if what.length != 1 { return }
|
||||||
|
|
||||||
|
// can be passed to types that are floats at a primitive level.
|
||||||
|
primitive := what.underlyingPrimitive()
|
||||||
|
switch primitive {
|
||||||
|
case
|
||||||
|
&PrimitiveF64,
|
||||||
|
&PrimitiveF32:
|
||||||
|
|
||||||
|
allowed = true
|
||||||
|
}
|
||||||
|
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"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// canBePassedAs returns true if this literal can be implicitly cast to the
|
||||||
|
// specified type, and false if it can't.
|
||||||
|
func (literal StringLiteral) canBePassedAs (what Type) (allowed bool) {
|
||||||
|
// can be passed to types that are numbers at a primitive level.
|
||||||
|
primitive := what.underlyingPrimitive()
|
||||||
|
switch primitive {
|
||||||
|
case
|
||||||
|
&PrimitiveF64,
|
||||||
|
&PrimitiveF32,
|
||||||
|
&PrimitiveI64,
|
||||||
|
&PrimitiveI32,
|
||||||
|
&PrimitiveI16,
|
||||||
|
&PrimitiveI8,
|
||||||
|
&PrimitiveInt,
|
||||||
|
&PrimitiveU64,
|
||||||
|
&PrimitiveU32,
|
||||||
|
&PrimitiveU16,
|
||||||
|
&PrimitiveU8,
|
||||||
|
&PrimitiveUInt:
|
||||||
|
|
||||||
|
allowed = true
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// ToString outputs the data in the argument as a string.
|
// ToString outputs the data in the argument as a string.
|
||||||
func (literal RuneLiteral) ToString (indent int) (output 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, "'\n"))
|
||||||
|
|||||||
@ -2,6 +2,8 @@ package analyzer
|
|||||||
|
|
||||||
// This is a global, cannonical list of primitive and built-in types.
|
// This is a global, cannonical list of primitive and built-in types.
|
||||||
|
|
||||||
|
var PrimitiveF32 = createPrimitive("Int", Type {})
|
||||||
|
var PrimitiveF64 = createPrimitive("Int", Type {})
|
||||||
var PrimitiveInt = createPrimitive("Int", Type {})
|
var PrimitiveInt = createPrimitive("Int", Type {})
|
||||||
var PrimitiveUInt = createPrimitive("UInt", Type {})
|
var PrimitiveUInt = createPrimitive("UInt", Type {})
|
||||||
var PrimitiveI8 = createPrimitive("I8", Type {})
|
var PrimitiveI8 = createPrimitive("I8", Type {})
|
||||||
|
|||||||
@ -16,21 +16,20 @@ const (
|
|||||||
|
|
||||||
// TypeKindVariableArray means it's an array of variable length.
|
// TypeKindVariableArray means it's an array of variable length.
|
||||||
TypeKindVariableArray
|
TypeKindVariableArray
|
||||||
|
|
||||||
// TypeKindObject means it's a structured type with members.
|
|
||||||
TypeKindObject
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Type represents a description of a type. It must eventually point to a
|
// Type represents a description of a type. It must eventually point to a
|
||||||
// TypeSection.
|
// TypeSection.
|
||||||
type Type struct {
|
type Type struct {
|
||||||
// one of these must be nil.
|
// one of these must be nil.
|
||||||
actual Section
|
actual *TypeSection
|
||||||
points *Type
|
points *Type
|
||||||
|
|
||||||
mutable bool
|
mutable bool
|
||||||
kind TypeKind
|
kind TypeKind
|
||||||
|
|
||||||
|
primitiveCache *TypeSection
|
||||||
|
|
||||||
// if this is greater than 1, it means that this is a fixed-length array
|
// if this is greater than 1, it means that this is a fixed-length array
|
||||||
// of whatever the type is. even if the type is a variable length array.
|
// of whatever the type is. even if the type is a variable length array.
|
||||||
// because literally why not.
|
// because literally why not.
|
||||||