fspl/parser/fspl/misc.go

102 lines
2.4 KiB
Go

package fsplParser
import "strconv"
import "git.tebibyte.media/fspl/fspl/lexer"
import "git.tebibyte.media/fspl/fspl/entity"
var descriptionSignature = "signature"
var startTokensSignature = []lexer.TokenKind { lexer.LBracket }
func (this *treeParser) parseSignature () (*entity.Signature, error) {
err := this.ExpectDesc(descriptionSignature, startTokensSignature...)
if err != nil { return nil, err }
pos := this.Pos()
err = this.ExpectNext(lexer.Ident)
if err != nil { return nil, err }
signature := &entity.Signature{
Pos: pos,
Name: this.Value(),
}
this.Next()
for {
err := this.ExpectDesc (
"parameter or signature end",
appendCopy(startTokensDeclaration, lexer.RBracket)...)
if err != nil { return nil, err }
if this.Kind() == lexer.RBracket { break }
parameter, err := this.parseDeclaration()
if err != nil { return nil, err }
signature.Arguments = append(signature.Arguments, parameter)
}
signature.Pos = signature.Position().Union(this.Pos())
this.Next()
if this.Kind() == lexer.Colon {
this.Next()
ret, err := this.parseType()
if err != nil { return nil, err }
signature.Return = ret
}
return signature, nil
}
func (this *treeParser) parseMember () (*entity.Member, error) {
err := this.ExpectDesc("struct member", lexer.Ident)
if err != nil { return nil, err }
name := this.Value()
pos := this.Pos()
err = this.ExpectNext(lexer.Colon)
if err != nil { return nil, err }
this.Next()
value, err := this.parseExpression()
if err != nil { return nil, err }
return &entity.Member {
Pos: pos,
Name: name,
Value: value,
}, nil
}
func parseInteger (value string) (int64, error) {
base := 10
if len(value) > 0 && value[0] == '0' {
base = 8
if len(value) > 1 {
switch value[1] {
case 'x':
value = value[2:]
base = 16
case 'b':
value = value[2:]
base = 1
}
}
}
integer, err := strconv.ParseInt(value, base, 64)
if err != nil { return 0, err }
return integer, nil
}
func parseFloat (value string) (float64, error) {
float, err := strconv.ParseFloat(value, 64)
if err != nil { return 0, err }
return float, nil
}
func prependCopy[ELEMENT any] (item ELEMENT, array []ELEMENT) []ELEMENT {
return append([]ELEMENT { item }, array...)
}
func appendCopy[ELEMENT any] (array []ELEMENT, items ...ELEMENT) []ELEMENT {
newArray := make([]ELEMENT, len(array) + len(items))
copy(newArray[copy(newArray, array):], items)
return newArray
}