diff --git a/ast/ast.go b/ast/ast.go index 023aa07..b81826c 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -54,19 +54,19 @@ func (p *Program) String() string { type Type string -type Argument struct { +type Parameter struct { Name string Type Type } type FunctionDeclaration struct { - Token token.Token // The token.FN - Body Expression - Name string - Args []Argument + Token token.Token // The token.FN + Body Expression + Name string + Parameters []Parameter } -func ArgsToString(args []Argument) string { +func ArgsToString(args []Parameter) string { var b strings.Builder for _, arg := range args { @@ -80,7 +80,7 @@ func (fd *FunctionDeclaration) declarationNode() {} func (fd *FunctionDeclaration) TokenLiteral() string { return fd.Token.Literal } func (fd *FunctionDeclaration) Tok() token.Token { return fd.Token } func (fd *FunctionDeclaration) String() string { - return fmt.Sprintf("fn %v(%v) = %v;", fd.Name, ArgsToString(fd.Args), fd.Body.String()) + return fmt.Sprintf("fn %v(%v) = %v;", fd.Name, ArgsToString(fd.Parameters), fd.Body.String()) } // Represents a Expression that we failed to parse @@ -265,3 +265,31 @@ func (ae *AssignmentExpression) Tok() token.Token { return ae.Token } func (ae *AssignmentExpression) String() string { return fmt.Sprintf("%s = %s", ae.Lhs.String(), ae.Rhs.String()) } + +// identifier ( expressions... ) +type FunctionCall struct { + Token token.Token // The identifier + Identifier string + Arguments []Expression +} + +func (fc *FunctionCall) expressionNode() {} +func (fc *FunctionCall) TokenLiteral() string { return fc.Token.Literal } +func (fc *FunctionCall) Tok() token.Token { return fc.Token } +func (fc *FunctionCall) String() string { + b := strings.Builder{} + + b.WriteString(fc.Identifier) + b.WriteRune('(') + + for i, arg := range fc.Arguments { + b.WriteString(arg.String()) + if i < (len(fc.Arguments) - 1) { + b.WriteRune(',') + } + } + + b.WriteRune(')') + + return b.String() +} diff --git a/design.md b/design.md index 95ae87c..59a7a0b 100644 --- a/design.md +++ b/design.md @@ -5,14 +5,21 @@ Playground for language design dessisions ## Function Calls ```tt -fn hi(hello: i32) = { - 3 +fn hi(arg1: i32, arg2: i32) = { + arg1 + + // Hi + arg2 }; fn main() = { - hi!; - hi(); - hi; + + // Args + + arg1 := 2; + arg2 := 2; + + //hi(arg1, arg2) |> hi(arg2); + //hi(arg1, arg2) |> hi(arg1, |); }; ``` diff --git a/parser/parser.go b/parser/parser.go index 475ca0d..30b03d9 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -186,23 +186,23 @@ func (p *Parser) parseType() (t ast.Type, ok bool) { return ast.Type(p.curToken.Literal), true } -func (p *Parser) parseArgumentList() ([]ast.Argument, bool) { - args := []ast.Argument{} +func (p *Parser) parseParameterList() ([]ast.Parameter, bool) { + parameters := []ast.Parameter{} for p.peekTokenIs(token.Ident) { p.nextToken() name := p.curToken.Literal if ok, _ := p.expectPeek(token.Colon); !ok { - return args, false + return parameters, false } p.nextToken() t, ok := p.parseType() if !ok { - return args, false + return parameters, false } - args = append(args, ast.Argument{Type: t, Name: name}) + parameters = append(parameters, ast.Parameter{Type: t, Name: name}) if !p.peekTokenIs(token.Comma) { break @@ -210,7 +210,7 @@ func (p *Parser) parseArgumentList() ([]ast.Argument, bool) { p.nextToken() } - return args, true + return parameters, true } func (p *Parser) parseDeclaration() ast.Declaration { @@ -227,7 +227,7 @@ func (p *Parser) parseDeclaration() ast.Declaration { return nil } - args, ok := p.parseArgumentList() + params, ok := p.parseParameterList() if !ok { return nil @@ -247,10 +247,10 @@ func (p *Parser) parseDeclaration() ast.Declaration { } return &ast.FunctionDeclaration{ - Token: tok, - Name: name, - Body: expr, - Args: args, + Token: tok, + Name: name, + Body: expr, + Parameters: params, } } @@ -390,6 +390,8 @@ func (p *Parser) parseVariable() ast.Expression { switch p.peekToken.Type { case token.Colon: return p.parseVariableDeclaration() + case token.OpenParen: + return p.parseFunctionCall() default: return &ast.VariableReference{ Token: p.curToken, @@ -427,6 +429,32 @@ func (p *Parser) parseVariableDeclaration() ast.Expression { return variable } +func (p *Parser) parseFunctionCall() ast.Expression { + if ok, errExpr := p.expect(token.Ident); !ok { + return errExpr + } + + funcCall := &ast.FunctionCall{Token: p.curToken, Identifier: p.curToken.Literal} + if ok, errExpr := p.expectPeek(token.OpenParen); !ok { + return errExpr + } + + args := []ast.Expression{} + + for !p.peekTokenIs(token.CloseParen) { + p.nextToken() + + args = append(args, p.parseExpression(PrecLowest)) + } + + // Move onto the ')' + p.nextToken() + + funcCall.Arguments = args + + return funcCall +} + // Binary func (p *Parser) parseBinaryExpression(lhs ast.Expression) ast.Expression { diff --git a/test.tt b/test.tt index 960c7a7..b0bbf95 100644 --- a/test.tt +++ b/test.tt @@ -1,11 +1,14 @@ fn main() = { i := 5; + if i == 5 { 0 } else { 1 - } + }; + + test2(3) }; fn test2(hello: i64) = { diff --git a/typechecker/infer.go b/typechecker/infer.go index 0c1fcb1..6f5883b 100644 --- a/typechecker/infer.go +++ b/typechecker/infer.go @@ -31,13 +31,13 @@ func (c *Checker) inferDeclaration(decl ast.Declaration) (tast.Declaration, erro case *ast.FunctionDeclaration: vars := make(Variables) arguments := []tast.Argument{} - for _, arg := range decl.Args { - t, ok := types.From(arg.Type) + for _, param := range decl.Parameters { + t, ok := types.From(param.Type) if !ok { - return nil, c.error(decl.Token, "could not find the type %q for argument %q", arg.Type, arg.Name) + return nil, c.error(decl.Token, "could not find the type %q for argument %q", param.Type, param.Name) } - vars[arg.Name] = t - arguments = append(arguments, tast.Argument{Name: arg.Name, Type: t}) + vars[param.Name] = t + arguments = append(arguments, tast.Argument{Name: param.Name, Type: t}) } body, err := c.inferExpression(vars, decl.Body) c.functionVariables[decl.Name] = vars diff --git a/typechecker/variable_resolution.go b/typechecker/variable_resolution.go index 40ac400..15fa022 100644 --- a/typechecker/variable_resolution.go +++ b/typechecker/variable_resolution.go @@ -79,9 +79,9 @@ func VarResolve(p *ast.Program) (map[string]Scope, error) { } s := Scope{Variables: make(map[string]Var)} - for i, arg := range d.Args { - uniq := s.SetUniq(arg.Name) - d.Args[i].Name = uniq + for i, param := range d.Parameters { + uniq := s.SetUniq(param.Name) + d.Parameters[i].Name = uniq } err := VarResolveExpr(&s, d.Body) functionToScope[d.Name] = s