Method and function parsing complete, without detail

This commit is contained in:
Sasha Koshka 2024-02-06 16:13:05 -05:00
parent 3c67cf576c
commit 1b50c8f879
2 changed files with 63 additions and 20 deletions

View File

@ -1,7 +1,11 @@
package parser
import "git.tebibyte.media/sashakoshka/fspl/lexer"
import "git.tebibyte.media/sashakoshka/fspl/entity"
var descriptionSignature = "Signature"
var startTokensSignature = []lexer.TokenKind { lexer.LBracket }
func (this *Parser) parseSignature () (*entity.Signature, error) {
// TODO
}

View File

@ -31,7 +31,10 @@ func (this *Parser) parseTopLevel () error {
// LBracket: Function
if this.token.Is(lexer.LBracket) {
return this.parseFunction(access)
function, err := this.parseFunction(access)
if err != nil { return err }
// TODO add toplevel entity
this.tree.AddDeclaration(function)
}
// TypeIdent: Method, or Typedef
@ -42,14 +45,18 @@ func (this *Parser) parseTopLevel () error {
switch token.Kind {
case lexer.Dot:
// Dot: Method
_, err = this.expect(lexer.LBracket)
_, err = this.expectDesc(descriptionSignature, startTokensSignature...)
if err != nil { return err }
return this.parseMethod(access, typeName)
method, err := this.parseMethod(access, typeName)
if err != nil { return err }
this.tree.AddDeclaration(method)
case lexer.Colon:
// Colon: Typedef
_, err = this.expect(startTokensType...)
if err != nil { return err }
return this.parseTypedef(access, typeName)
typedef, err := this.parseTypedef(access, typeName)
if err != nil { return err }
this.tree.AddDeclaration(typedef)
}
return nil
}
@ -65,28 +72,60 @@ func (this *Parser) parseAccess () (entity.Access, error) {
}
}
func (this *Parser) parseFunction (access entity.Access) error {
func (this *Parser) parseFunction (access entity.Access) (*entity.Function, error) {
signature, err := this.parseSignature()
if err != nil { return err }
token, err := this.expectDesc (
"Function body, Link name, " + descriptionTopLevel,
appendr(lexer.Symbol, appendr(lexer.String, startTokensTopLevel))...)
if err != nil { return err }
if err != nil { return nil, err }
switch token.Kind {
function := &entity.Function {
Acc: access,
Signature: signature,
}
// TODO there will be a lot of code duplication between this and parseMethod
// if we keep continuing along this route, need only one function to parse
// both
token, err := this.expectDesc (
"Function body, Link name, " + descriptionTopLevel,
appendCopy(startTokensTopLevel, lexer.Symbol, lexer.String)...)
if err != nil { return nil, err }
if token.Is(lexer.String) {
// String: Link name
function.LinkName = token.Value
token, err = this.expectDesc (
"Function body, " + descriptionTopLevel,
appendCopy(startTokensTopLevel, lexer.Symbol)...)
if err != nil { return nil, err }
}
if token.Is(startTokensTopLevel...) {
// startTokensTopLevel: function has no body and is finished,
// move on to next top level declaration or graceful EOF.
return function, nil
}
// Symbol '=': Function body
err = this.expectValueDesc("Function body", lexer.Symbol, "=")
if err != nil { return nil, err }
// Expression
_, err = this.expectDesc(descriptionExpression, startTokensExpression...)
if err != nil { return nil, err }
bodyExpression, err := this.parseExpression()
if err != nil { return nil, err }
function.Body = bodyExpression
return function, nil
}
func (this *Parser) parseMethod (access entity.Access, typeName string) error {
signature, err := this.parseSignature()
if err != nil { return err }
func (this *Parser) parseMethod (access entity.Access, typeName string) (*entity.Method, error) {
function, err := this.parseFunction(access)
if err != nil { return nil, err }
return &entity.Method {
Acc: function.Acc,
TypeName: typeName,
Signature: function.Signature,
LinkName: function.LinkName,
Body: function.Body,
}, nil
}
func (this *Parser) parseTypedef (access entity.Access, typeName string) error {
func (this *Parser) parseTypedef (access entity.Access, typeName string) (*entity.Typedef, error) {
}