153 lines
3.3 KiB
Go
153 lines
3.3 KiB
Go
package analyzer
|
|
|
|
// import "fmt"
|
|
import "github.com/alecthomas/participle/v2"
|
|
import "git.tebibyte.media/sashakoshka/fspl/entity"
|
|
|
|
func (this *Tree) analyzeLiteralInt (
|
|
into entity.Type,
|
|
mode strictness,
|
|
literal *entity.LiteralInt,
|
|
) (
|
|
entity.Expression,
|
|
error,
|
|
) {
|
|
if !this.isNumeric(into) {
|
|
return nil, participle.Errorf (
|
|
literal.Pos, "cannot use integer literal as %v",
|
|
into)
|
|
}
|
|
|
|
if this.isInteger(into) && !this.inRange(into, int64(literal.Value)) {
|
|
return nil, participle.Errorf (
|
|
literal.Pos, "integer literal out of range for type %v",
|
|
into)
|
|
}
|
|
|
|
literal.Ty = into
|
|
return literal, nil
|
|
}
|
|
|
|
func (this *Tree) analyzeLiteralFloat (
|
|
into entity.Type,
|
|
mode strictness,
|
|
literal *entity.LiteralFloat,
|
|
) (
|
|
entity.Expression,
|
|
error,
|
|
) {
|
|
if !this.isFloat(into) {
|
|
return nil, participle.Errorf (
|
|
literal.Pos, "cannot use float literal as %v",
|
|
into)
|
|
}
|
|
|
|
literal.Ty = into
|
|
return literal, nil
|
|
}
|
|
|
|
func (this *Tree) analyzeLiteralArray (
|
|
into entity.Type,
|
|
mode strictness,
|
|
literal *entity.LiteralArray,
|
|
) (
|
|
entity.Expression,
|
|
error,
|
|
) {
|
|
base, ok := this.reduceToBase(into).(*entity.TypeArray)
|
|
if !ok {
|
|
return nil, participle.Errorf (
|
|
literal.Pos, "cannot use array literal as %v",
|
|
into)
|
|
}
|
|
|
|
if base.Length != len(literal.Elements) {
|
|
return nil, participle.Errorf (
|
|
literal.Pos, "expected %v elements",
|
|
base.Length)
|
|
}
|
|
|
|
for index, element := range literal.Elements {
|
|
element, err := this.analyzeExpression(base.Element, strict, element)
|
|
if err != nil { return nil, err }
|
|
literal.Elements[index] = element
|
|
}
|
|
|
|
literal.Ty = into
|
|
return literal, nil
|
|
}
|
|
|
|
func (this *Tree) analyzeLiteralStruct (
|
|
into entity.Type,
|
|
mode strictness,
|
|
literal *entity.LiteralStruct,
|
|
) (
|
|
entity.Expression,
|
|
error,
|
|
) {
|
|
base, ok := this.reduceToBase(into).(*entity.TypeStruct)
|
|
if !ok {
|
|
return nil, participle.Errorf (
|
|
literal.Pos, "cannot use struct literal as %v",
|
|
into)
|
|
}
|
|
|
|
literal, err := this.assembleStructLiteralMap(literal)
|
|
if err != nil { return nil, err }
|
|
|
|
for name, member := range literal.MemberMap {
|
|
correct, ok := base.MemberMap[name]
|
|
if !ok {
|
|
return nil, participle.Errorf (
|
|
literal.Pos, "no member %v.%s",
|
|
into, name)
|
|
}
|
|
|
|
value, err := this.analyzeExpression(correct.Type(), strict, member.Value)
|
|
if err != nil { return nil, err }
|
|
member.Value = value
|
|
}
|
|
|
|
literal.Ty = into
|
|
return literal, nil
|
|
}
|
|
|
|
func (this *Tree) analyzeLiteralBoolean (
|
|
into entity.Type,
|
|
mode strictness,
|
|
literal *entity.LiteralBoolean,
|
|
) (
|
|
entity.Expression,
|
|
error,
|
|
) {
|
|
if !this.isBoolean(into) {
|
|
return nil, participle.Errorf (
|
|
literal.Pos, "cannot use boolean literal as %v",
|
|
into)
|
|
}
|
|
|
|
literal.Ty = into
|
|
return literal, nil
|
|
}
|
|
|
|
func (this *Tree) assembleStructLiteralMap (
|
|
literal *entity.LiteralStruct,
|
|
) (
|
|
*entity.LiteralStruct,
|
|
error,
|
|
) {
|
|
literal.MemberMap = make(map[string] *entity.Member)
|
|
literal.MemberOrder = make([]string, len(literal.Members))
|
|
for index, member := range literal.Members {
|
|
if previous, exists := literal.MemberMap[member.Name]; exists {
|
|
return literal, participle.Errorf (
|
|
member.Pos, "%s already listed in struct literal at %v",
|
|
member.Name, previous.Pos)
|
|
}
|
|
literal.MemberMap [member.Name] = member
|
|
literal.MemberOrder[index] = member.Name
|
|
literal.Members [index] = member
|
|
}
|
|
return literal, nil
|
|
}
|