Added some useful type checking thigns to literals

This commit is contained in:
Sasha Koshka 2022-10-04 16:19:26 -04:00
parent e2947eab8c
commit 5c286cf955
4 changed files with 177 additions and 7 deletions

View File

@ -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

View File

@ -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"))

View File

@ -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 {})

View File

@ -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.