From f8ed70336d6288f6102d23865d62653863056bfc Mon Sep 17 00:00:00 2001 From: MrLetsplay Date: Tue, 12 Mar 2024 22:00:03 +0100 Subject: [PATCH] More function parsing --- example/helloworld.lang | 2 +- parser.go | 81 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 5 deletions(-) diff --git a/example/helloworld.lang b/example/helloworld.lang index 34cbb87..97a886f 100644 --- a/example/helloworld.lang +++ b/example/helloworld.lang @@ -1,7 +1,7 @@ import lang.stdlib; (u8, u8) a(u8 a, u8 b) { - return a, b + return a, b; } void main() { diff --git a/parser.go b/parser.go index 2a8c01b..c547689 100644 --- a/parser.go +++ b/parser.go @@ -108,8 +108,14 @@ type Block struct { Statements []Statement } +type ParsedParameter struct { + Name string + Type Type +} + type ParsedFunction struct { - Parameters []Type + Name string + Parameters []ParsedParameter ReturnType Type Body Block } @@ -141,6 +147,19 @@ func expectSeparator(tokens []LexToken, separators ...Separator) (Separator, []L return separator.Value.(Separator), tokens[1:], nil } +func expectIdentifier(tokens []LexToken) (string, []LexToken, error) { + if len(tokens) == 0 { + return "", nil, errors.New("expected identifier") + } + + token := tokens[0] + if token.Type != Type_Separator && token.Type != Type_Identifier { + return "", nil, errors.New("expected identifier") + } + + return token.Value.(string), tokens[1:], nil +} + func parseImport(tokens []LexToken) (*Import, []LexToken, error) { var err error @@ -216,7 +235,8 @@ func parseType(tokens []LexToken) (*Type, []LexToken, error) { func parseFunction(tokens []LexToken) (*ParsedFunction, []LexToken, error) { var err error - var parameters []Type + var name string + var parameters []ParsedParameter var returnType *Type var body Block @@ -225,9 +245,62 @@ func parseFunction(tokens []LexToken) (*ParsedFunction, []LexToken, error) { return nil, nil, err } - // TODO: function name, parameters, body + if len(tokens) < 2 { + return nil, nil, errors.New("incomplete function declaration") + } - return &ParsedFunction{Parameters: parameters, ReturnType: *returnType, Body: body}, tokens, nil + name, tokens, err = expectIdentifier(tokens) + if err != nil { + return nil, nil, err + } + + _, tokens, err = expectSeparator(tokens, Separator_OpenParen) + if err != nil { + return nil, nil, err + } + + for { + if len(tokens) == 0 { + return nil, nil, errors.New("incomplete function declaration") + } + + token := tokens[0] + if token.Type == Type_Separator && token.Value.(Separator) == Separator_CloseParen { + tokens = tokens[1:] + break + } + + if len(parameters) > 0 { + if token.Type != Type_Separator && token.Value.(Separator) != Separator_Comma { + return nil, nil, errors.New("expected ,") + } + + tokens = tokens[1:] + } + + var paramType *Type + paramType, tokens, err = parseType(tokens) + if err != nil { + return nil, nil, err + } + + var paramName string + paramName, tokens, err = expectIdentifier(tokens) + if err != nil { + return nil, nil, err + } + + parameters = append(parameters, ParsedParameter{Name: paramName, Type: *paramType}) + } + + _, tokens, err = expectSeparator(tokens, Separator_OpenCurly) + if err != nil { + return nil, nil, err + } + + // TODO: body, closing curly + + return &ParsedFunction{Name: name, Parameters: parameters, ReturnType: *returnType, Body: body}, tokens, nil } func parser(tokens []LexToken) (*ParsedFile, error) {