102 lines
2.4 KiB
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
|
|
}
|