mirror of
https://github.com/RoBaertschi/tt.git
synced 2025-04-16 05:53:30 +00:00
begin with variables
This commit is contained in:
parent
1d70a700c9
commit
bae6aa05fc
25
ast/ast.go
25
ast/ast.go
@ -190,3 +190,28 @@ func (ie *IfExpression) String() string {
|
|||||||
|
|
||||||
return builder.String()
|
return builder.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is still a expression, because making it some other type of node would be to much work
|
||||||
|
type VariableDeclaration struct {
|
||||||
|
Token token.Token // The Identifier token
|
||||||
|
InitializingExpression Expression
|
||||||
|
Type string
|
||||||
|
Identifier string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vd *VariableDeclaration) expressionNode() {}
|
||||||
|
func (vd *VariableDeclaration) TokenLiteral() string { return vd.Token.Literal }
|
||||||
|
func (vd *VariableDeclaration) String() string {
|
||||||
|
return fmt.Sprintf("%s : %v = %s", vd.Identifier, vd.Type, vd.InitializingExpression)
|
||||||
|
}
|
||||||
|
|
||||||
|
type VariableReference struct {
|
||||||
|
Token token.Token // The identifier token
|
||||||
|
Identifier string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vr *VariableReference) expressionNode() {}
|
||||||
|
func (vr *VariableReference) TokenLiteral() string { return vr.Token.Literal }
|
||||||
|
func (vr *VariableReference) String() string {
|
||||||
|
return fmt.Sprintf("%s", vr.Identifier)
|
||||||
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
```tt
|
```tt
|
||||||
// Return type is i64
|
// Return type is i64
|
||||||
fn main() = {
|
fn main() = {
|
||||||
let i = 34;
|
i : = 3;
|
||||||
i
|
i
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
117
parser/parser.go
117
parser/parser.go
@ -57,6 +57,7 @@ func New(l *lexer.Lexer) *Parser {
|
|||||||
p.registerPrefixFn(token.OpenParen, p.parseGroupedExpression)
|
p.registerPrefixFn(token.OpenParen, p.parseGroupedExpression)
|
||||||
p.registerPrefixFn(token.OpenBrack, p.parseBlockExpression)
|
p.registerPrefixFn(token.OpenBrack, p.parseBlockExpression)
|
||||||
p.registerPrefixFn(token.If, p.parseIfExpression)
|
p.registerPrefixFn(token.If, p.parseIfExpression)
|
||||||
|
p.registerPrefixFn(token.Ident, p.parseVariable)
|
||||||
|
|
||||||
p.infixParseFns = make(map[token.TokenType]infixParseFn)
|
p.infixParseFns = make(map[token.TokenType]infixParseFn)
|
||||||
p.registerInfixFn(token.Plus, p.parseBinaryExpression)
|
p.registerInfixFn(token.Plus, p.parseBinaryExpression)
|
||||||
@ -264,41 +265,6 @@ func (p *Parser) parseBooleanExpression() ast.Expression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) parseBinaryExpression(lhs ast.Expression) ast.Expression {
|
|
||||||
var op ast.BinaryOperator
|
|
||||||
switch p.curToken.Type {
|
|
||||||
case token.Plus:
|
|
||||||
op = ast.Add
|
|
||||||
case token.Minus:
|
|
||||||
op = ast.Subtract
|
|
||||||
case token.Asterisk:
|
|
||||||
op = ast.Multiply
|
|
||||||
case token.Slash:
|
|
||||||
op = ast.Divide
|
|
||||||
case token.DoubleEqual:
|
|
||||||
op = ast.Equal
|
|
||||||
case token.NotEqual:
|
|
||||||
op = ast.NotEqual
|
|
||||||
case token.LessThan:
|
|
||||||
op = ast.LessThan
|
|
||||||
case token.LessThanEqual:
|
|
||||||
op = ast.LessThanEqual
|
|
||||||
case token.GreaterThan:
|
|
||||||
op = ast.GreaterThan
|
|
||||||
case token.GreaterThanEqual:
|
|
||||||
op = ast.GreaterThanEqual
|
|
||||||
default:
|
|
||||||
return p.exprError(p.curToken, "invalid token for binary expression %s", p.curToken.Type)
|
|
||||||
}
|
|
||||||
tok := p.curToken
|
|
||||||
|
|
||||||
precedence := p.curPrecedence()
|
|
||||||
p.nextToken()
|
|
||||||
rhs := p.parseExpression(precedence)
|
|
||||||
|
|
||||||
return &ast.BinaryExpression{Lhs: lhs, Rhs: rhs, Operator: op, Token: tok}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Parser) parseGroupedExpression() ast.Expression {
|
func (p *Parser) parseGroupedExpression() ast.Expression {
|
||||||
p.expect(token.OpenParen)
|
p.expect(token.OpenParen)
|
||||||
|
|
||||||
@ -368,3 +334,84 @@ func (p *Parser) parseIfExpression() ast.Expression {
|
|||||||
|
|
||||||
return ifExpr
|
return ifExpr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Parser) parseVariable() ast.Expression {
|
||||||
|
if ok, errExpr := p.expect(token.Ident); !ok {
|
||||||
|
return errExpr
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.peekTokenIs(token.Colon) {
|
||||||
|
return p.parseVariableDeclaration()
|
||||||
|
} else {
|
||||||
|
return &ast.VariableReference{
|
||||||
|
Token: p.curToken,
|
||||||
|
Identifier: p.curToken.Literal,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME(Robin): Add variable references
|
||||||
|
// Lets panic about deez nuts of yours
|
||||||
|
panic("deez nuts")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parser) parseVariableDeclaration() ast.Expression {
|
||||||
|
if ok, errExpr := p.expect(token.Ident); !ok {
|
||||||
|
return errExpr
|
||||||
|
}
|
||||||
|
|
||||||
|
variable := &ast.VariableDeclaration{Token: p.curToken, Identifier: p.curToken.Literal}
|
||||||
|
if ok, errExpr := p.expectPeek(token.Colon); !ok {
|
||||||
|
return errExpr
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.peekTokenIs(token.Ident) {
|
||||||
|
p.nextToken()
|
||||||
|
variable.Type = p.curToken.Literal
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok, errExpr := p.expectPeek(token.Equal); !ok {
|
||||||
|
return errExpr
|
||||||
|
}
|
||||||
|
|
||||||
|
p.nextToken()
|
||||||
|
variable.InitializingExpression = p.parseExpression(PrecLowest)
|
||||||
|
|
||||||
|
return variable
|
||||||
|
}
|
||||||
|
|
||||||
|
// Binary
|
||||||
|
|
||||||
|
func (p *Parser) parseBinaryExpression(lhs ast.Expression) ast.Expression {
|
||||||
|
var op ast.BinaryOperator
|
||||||
|
switch p.curToken.Type {
|
||||||
|
case token.Plus:
|
||||||
|
op = ast.Add
|
||||||
|
case token.Minus:
|
||||||
|
op = ast.Subtract
|
||||||
|
case token.Asterisk:
|
||||||
|
op = ast.Multiply
|
||||||
|
case token.Slash:
|
||||||
|
op = ast.Divide
|
||||||
|
case token.DoubleEqual:
|
||||||
|
op = ast.Equal
|
||||||
|
case token.NotEqual:
|
||||||
|
op = ast.NotEqual
|
||||||
|
case token.LessThan:
|
||||||
|
op = ast.LessThan
|
||||||
|
case token.LessThanEqual:
|
||||||
|
op = ast.LessThanEqual
|
||||||
|
case token.GreaterThan:
|
||||||
|
op = ast.GreaterThan
|
||||||
|
case token.GreaterThanEqual:
|
||||||
|
op = ast.GreaterThanEqual
|
||||||
|
default:
|
||||||
|
return p.exprError(p.curToken, "invalid token for binary expression %s", p.curToken.Type)
|
||||||
|
}
|
||||||
|
tok := p.curToken
|
||||||
|
|
||||||
|
precedence := p.curPrecedence()
|
||||||
|
p.nextToken()
|
||||||
|
rhs := p.parseExpression(precedence)
|
||||||
|
|
||||||
|
return &ast.BinaryExpression{Lhs: lhs, Rhs: rhs, Operator: op, Token: tok}
|
||||||
|
}
|
||||||
|
32
tast/tast.go
32
tast/tast.go
@ -169,3 +169,35 @@ func (ie *IfExpression) String() string {
|
|||||||
|
|
||||||
return builder.String()
|
return builder.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is still a expression, because making it some other type of node would be to much work
|
||||||
|
type VariableDeclaration struct {
|
||||||
|
Token token.Token // The Identifier token
|
||||||
|
InitializingExpression Expression
|
||||||
|
VariableType types.Type
|
||||||
|
Identifier string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vd *VariableDeclaration) expressionNode() {}
|
||||||
|
func (vd *VariableDeclaration) Type() types.Type {
|
||||||
|
return vd.VariableType
|
||||||
|
}
|
||||||
|
func (vd *VariableDeclaration) TokenLiteral() string { return vd.Token.Literal }
|
||||||
|
func (vd *VariableDeclaration) String() string {
|
||||||
|
return fmt.Sprintf("%s : %v = %s", vd.Identifier, vd.Type().Name(), vd.InitializingExpression)
|
||||||
|
}
|
||||||
|
|
||||||
|
type VariableReference struct {
|
||||||
|
Token token.Token // The identifier token
|
||||||
|
Identifier string
|
||||||
|
VariableType types.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vr *VariableReference) expressionNode() {}
|
||||||
|
func (vr *VariableReference) Type() types.Type {
|
||||||
|
return vr.VariableType
|
||||||
|
}
|
||||||
|
func (vr *VariableReference) TokenLiteral() string { return vr.Token.Literal }
|
||||||
|
func (vr *VariableReference) String() string {
|
||||||
|
return fmt.Sprintf("%s", vr.Identifier)
|
||||||
|
}
|
||||||
|
1
typechecker/variable_resolution.go
Normal file
1
typechecker/variable_resolution.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package typechecker
|
Loading…
x
Reference in New Issue
Block a user