Added isSingular to method (this is cool)

This commit is contained in:
Sasha Koshka 2022-10-11 16:20:12 -04:00
parent b8c57d5a56
commit 020833c4c6
2 changed files with 29 additions and 8 deletions

View File

@ -18,7 +18,7 @@ func (literal IntLiteral) ToString (indent int) (output string) {
// 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) {
// must be a singlular value // must be a singlular value
if what.length != 1 { return } if !what.isSingular() { return }
// can be passed to types that are signed numbers at a primitive level. // can be passed to types that are signed numbers at a primitive level.
primitive := what.underlyingPrimitive() primitive := what.underlyingPrimitive()
@ -47,7 +47,7 @@ func (literal UIntLiteral) ToString (indent int) (output string) {
// 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) {
// must be a singlular value // must be a singlular value
if what.length != 1 { return } if !what.isSingular() { return }
// can be passed to types that are numbers at a primitive level. // can be passed to types that are numbers at a primitive level.
primitive := what.underlyingPrimitive() primitive := what.underlyingPrimitive()
@ -81,7 +81,7 @@ func (literal FloatLiteral) ToString (indent int) (output string) {
// specified type, and false if it can't. // specified type, and false if it can't.
func (literal FloatLiteral) canBePassedAs (what Type) (allowed bool) { func (literal FloatLiteral) canBePassedAs (what Type) (allowed bool) {
// must be a singlular value // must be a singlular value
if what.length != 1 { return } if !what.isSingular() { return }
// can be passed to types that are floats at a primitive level. // can be passed to types that are floats at a primitive level.
primitive := what.underlyingPrimitive() primitive := what.underlyingPrimitive()
@ -108,12 +108,11 @@ func (literal StringLiteral) canBePassedAs (what Type) (allowed bool) {
// types that can be reduced to a variable array pointing to numbers at // types that can be reduced to a variable array pointing to numbers at
// a primitive level. // a primitive level.
what, worked := what.reduce() reduced, worked := what.reduce()
if worked { if worked {
// TODO: make some method to check the total length of a type if !what.isSingular() { return }
if what.length != 1 { return } if reduced.kind != TypeKindVariableArray { return }
what = reduced
if what.kind != TypeKindVariableArray { return }
} }
primitive := what.underlyingPrimitive() primitive := what.underlyingPrimitive()

View File

@ -29,6 +29,7 @@ type Type struct {
kind TypeKind kind TypeKind
primitiveCache *TypeSection primitiveCache *TypeSection
singularCache *bool
// 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.
@ -114,6 +115,27 @@ func (what Type) underlyingPrimitive () (underlying *TypeSection) {
} }
} }
// isSingular returns whether or not the type is a singular value. this goes
// all the way up the inheritence chain, only stopping when it hits a non-basic
// type because this is about data storage of a value.
func (what Type) isSingular () (singular bool) {
// if we have already done this operation, return the cahced result.
if what.singularCache != nil {
singular = *what.singularCache
return
}
// decide whether or not to recurse
if what.kind != TypeKindBasic { return }
actual := what.actual
if actual == nil {
return
} else {
singular = actual.what.isSingular()
}
return
}
// reduce ascends up the inheritence chain and gets the first type it finds that // reduce ascends up the inheritence chain and gets the first type it finds that
// isn't basic. If the type has a clear path of inheritence to a simple // isn't basic. If the type has a clear path of inheritence to a simple
// primitive, there will be no non-basic types in the chain and this method will // primitive, there will be no non-basic types in the chain and this method will