mirror of
https://github.com/RoBaertschi/tt.git
synced 2025-04-16 05:53:30 +00:00
begin function calls
parser done
This commit is contained in:
parent
ee2d23e97f
commit
19c8cb9103
42
ast/ast.go
42
ast/ast.go
@ -54,19 +54,19 @@ func (p *Program) String() string {
|
|||||||
|
|
||||||
type Type string
|
type Type string
|
||||||
|
|
||||||
type Argument struct {
|
type Parameter struct {
|
||||||
Name string
|
Name string
|
||||||
Type Type
|
Type Type
|
||||||
}
|
}
|
||||||
|
|
||||||
type FunctionDeclaration struct {
|
type FunctionDeclaration struct {
|
||||||
Token token.Token // The token.FN
|
Token token.Token // The token.FN
|
||||||
Body Expression
|
Body Expression
|
||||||
Name string
|
Name string
|
||||||
Args []Argument
|
Parameters []Parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
func ArgsToString(args []Argument) string {
|
func ArgsToString(args []Parameter) string {
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
|
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
@ -80,7 +80,7 @@ func (fd *FunctionDeclaration) declarationNode() {}
|
|||||||
func (fd *FunctionDeclaration) TokenLiteral() string { return fd.Token.Literal }
|
func (fd *FunctionDeclaration) TokenLiteral() string { return fd.Token.Literal }
|
||||||
func (fd *FunctionDeclaration) Tok() token.Token { return fd.Token }
|
func (fd *FunctionDeclaration) Tok() token.Token { return fd.Token }
|
||||||
func (fd *FunctionDeclaration) String() string {
|
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
|
// 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 {
|
func (ae *AssignmentExpression) String() string {
|
||||||
return fmt.Sprintf("%s = %s", ae.Lhs.String(), ae.Rhs.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()
|
||||||
|
}
|
||||||
|
17
design.md
17
design.md
@ -5,14 +5,21 @@ Playground for language design dessisions
|
|||||||
## Function Calls
|
## Function Calls
|
||||||
|
|
||||||
```tt
|
```tt
|
||||||
fn hi(hello: i32) = {
|
fn hi(arg1: i32, arg2: i32) = {
|
||||||
3
|
arg1 +
|
||||||
|
// Hi
|
||||||
|
arg2
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() = {
|
fn main() = {
|
||||||
hi!;
|
|
||||||
hi();
|
// Args
|
||||||
hi;
|
|
||||||
|
arg1 := 2;
|
||||||
|
arg2 := 2;
|
||||||
|
|
||||||
|
//hi(arg1, arg2) |> hi(arg2);
|
||||||
|
//hi(arg1, arg2) |> hi(arg1, |);
|
||||||
};
|
};
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -186,23 +186,23 @@ func (p *Parser) parseType() (t ast.Type, ok bool) {
|
|||||||
return ast.Type(p.curToken.Literal), true
|
return ast.Type(p.curToken.Literal), true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) parseArgumentList() ([]ast.Argument, bool) {
|
func (p *Parser) parseParameterList() ([]ast.Parameter, bool) {
|
||||||
args := []ast.Argument{}
|
parameters := []ast.Parameter{}
|
||||||
|
|
||||||
for p.peekTokenIs(token.Ident) {
|
for p.peekTokenIs(token.Ident) {
|
||||||
p.nextToken()
|
p.nextToken()
|
||||||
name := p.curToken.Literal
|
name := p.curToken.Literal
|
||||||
if ok, _ := p.expectPeek(token.Colon); !ok {
|
if ok, _ := p.expectPeek(token.Colon); !ok {
|
||||||
return args, false
|
return parameters, false
|
||||||
}
|
}
|
||||||
p.nextToken()
|
p.nextToken()
|
||||||
t, ok := p.parseType()
|
t, ok := p.parseType()
|
||||||
|
|
||||||
if !ok {
|
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) {
|
if !p.peekTokenIs(token.Comma) {
|
||||||
break
|
break
|
||||||
@ -210,7 +210,7 @@ func (p *Parser) parseArgumentList() ([]ast.Argument, bool) {
|
|||||||
p.nextToken()
|
p.nextToken()
|
||||||
}
|
}
|
||||||
|
|
||||||
return args, true
|
return parameters, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) parseDeclaration() ast.Declaration {
|
func (p *Parser) parseDeclaration() ast.Declaration {
|
||||||
@ -227,7 +227,7 @@ func (p *Parser) parseDeclaration() ast.Declaration {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
args, ok := p.parseArgumentList()
|
params, ok := p.parseParameterList()
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
@ -247,10 +247,10 @@ func (p *Parser) parseDeclaration() ast.Declaration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &ast.FunctionDeclaration{
|
return &ast.FunctionDeclaration{
|
||||||
Token: tok,
|
Token: tok,
|
||||||
Name: name,
|
Name: name,
|
||||||
Body: expr,
|
Body: expr,
|
||||||
Args: args,
|
Parameters: params,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,6 +390,8 @@ func (p *Parser) parseVariable() ast.Expression {
|
|||||||
switch p.peekToken.Type {
|
switch p.peekToken.Type {
|
||||||
case token.Colon:
|
case token.Colon:
|
||||||
return p.parseVariableDeclaration()
|
return p.parseVariableDeclaration()
|
||||||
|
case token.OpenParen:
|
||||||
|
return p.parseFunctionCall()
|
||||||
default:
|
default:
|
||||||
return &ast.VariableReference{
|
return &ast.VariableReference{
|
||||||
Token: p.curToken,
|
Token: p.curToken,
|
||||||
@ -427,6 +429,32 @@ func (p *Parser) parseVariableDeclaration() ast.Expression {
|
|||||||
return variable
|
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
|
// Binary
|
||||||
|
|
||||||
func (p *Parser) parseBinaryExpression(lhs ast.Expression) ast.Expression {
|
func (p *Parser) parseBinaryExpression(lhs ast.Expression) ast.Expression {
|
||||||
|
5
test.tt
5
test.tt
@ -1,11 +1,14 @@
|
|||||||
fn main() = {
|
fn main() = {
|
||||||
i := 5;
|
i := 5;
|
||||||
|
|
||||||
|
|
||||||
if i == 5 {
|
if i == 5 {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
1
|
1
|
||||||
}
|
};
|
||||||
|
|
||||||
|
test2(3)
|
||||||
};
|
};
|
||||||
|
|
||||||
fn test2(hello: i64) = {
|
fn test2(hello: i64) = {
|
||||||
|
@ -31,13 +31,13 @@ func (c *Checker) inferDeclaration(decl ast.Declaration) (tast.Declaration, erro
|
|||||||
case *ast.FunctionDeclaration:
|
case *ast.FunctionDeclaration:
|
||||||
vars := make(Variables)
|
vars := make(Variables)
|
||||||
arguments := []tast.Argument{}
|
arguments := []tast.Argument{}
|
||||||
for _, arg := range decl.Args {
|
for _, param := range decl.Parameters {
|
||||||
t, ok := types.From(arg.Type)
|
t, ok := types.From(param.Type)
|
||||||
if !ok {
|
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
|
vars[param.Name] = t
|
||||||
arguments = append(arguments, tast.Argument{Name: arg.Name, Type: t})
|
arguments = append(arguments, tast.Argument{Name: param.Name, Type: t})
|
||||||
}
|
}
|
||||||
body, err := c.inferExpression(vars, decl.Body)
|
body, err := c.inferExpression(vars, decl.Body)
|
||||||
c.functionVariables[decl.Name] = vars
|
c.functionVariables[decl.Name] = vars
|
||||||
|
@ -79,9 +79,9 @@ func VarResolve(p *ast.Program) (map[string]Scope, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s := Scope{Variables: make(map[string]Var)}
|
s := Scope{Variables: make(map[string]Var)}
|
||||||
for i, arg := range d.Args {
|
for i, param := range d.Parameters {
|
||||||
uniq := s.SetUniq(arg.Name)
|
uniq := s.SetUniq(param.Name)
|
||||||
d.Args[i].Name = uniq
|
d.Parameters[i].Name = uniq
|
||||||
}
|
}
|
||||||
err := VarResolveExpr(&s, d.Body)
|
err := VarResolveExpr(&s, d.Body)
|
||||||
functionToScope[d.Name] = s
|
functionToScope[d.Name] = s
|
||||||
|
Loading…
x
Reference in New Issue
Block a user