mighty

The mighty programming language, compiler and tools (WIP)
Log | Files | Refs

parser.go (2666B)


      1 package parser
      2 
      3 import (
      4 	"fmt"
      5 	"mighty/lexer"
      6 )
      7 
      8 type Expr interface{ expr_node() }
      9 
     10 type Ident struct{ Name string }
     11 
     12 func (Ident) expr_node() {}
     13 
     14 type LitInt struct{ Value string }
     15 
     16 func (LitInt) expr_node() {}
     17 
     18 type LitStr struct{ Value string }
     19 
     20 func (LitStr) expr_node() {}
     21 
     22 type Binary struct {
     23 	Op    lexer.Kind
     24 	Left  Expr
     25 	Right Expr
     26 }
     27 
     28 func (Binary) expr_node() {}
     29 
     30 type Call struct {
     31 	Callee Expr
     32 	Args   []Expr
     33 }
     34 
     35 func (Call) expr_node() {}
     36 
     37 type Parser struct {
     38 	tokens []lexer.Token
     39 	pos    int
     40 	errs   []error
     41 }
     42 
     43 func ParseExpr(tokens []lexer.Token) (Expr, []error) {
     44 
     45 	p := Parser{tokens: tokens}
     46 	expr := p.expr(0)
     47 
     48 	return expr, p.errs
     49 }
     50 
     51 func (p *Parser) expr(minPrec int) Expr {
     52 
     53 	left := p.postfix()
     54 
     55 	for {
     56 		op := p.peek().Kind
     57 		prec := precedence(op)
     58 
     59 		if prec < minPrec {
     60 			break
     61 		}
     62 
     63 		p.advance()
     64 
     65 		right := p.expr(prec + 1)
     66 
     67 		left = Binary{Op: op, Left: left, Right: right}
     68 	}
     69 
     70 	return left
     71 
     72 }
     73 
     74 func (p *Parser) postfix() Expr {
     75 	left := p.primary()
     76 
     77 	for p.match(lexer.LParen) {
     78 		var args []Expr
     79 
     80 		if !p.check(lexer.RParen) {
     81 
     82 			for {
     83 				args = append(args, p.expr(0))
     84 				if !p.match(lexer.Comma) {
     85 					break
     86 				}
     87 			}
     88 		}
     89 		p.expect(lexer.RParen, "expected ')' after call arguments")
     90 		left = Call{Callee: left, Args: args}
     91 
     92 	}
     93 	return left
     94 
     95 }
     96 
     97 func (p *Parser) primary() Expr {
     98 	tok := p.advance()
     99 
    100 	switch tok.Kind {
    101 
    102 	case lexer.Ident:
    103 		return Ident{Name: tok.Value}
    104 	case lexer.LiteralInt:
    105 		return LitInt{Value: tok.Value}
    106 	case lexer.LiteralString:
    107 		return LitStr{Value: tok.Value}
    108 	case lexer.LParen:
    109 		expr := p.expr(0)
    110 		p.expect(lexer.RParen, "expected ')' after expression")
    111 		return expr
    112 	default:
    113 		p.err(tok, "expected expression")
    114 		return Ident{Name: "<error>"}
    115 	}
    116 }
    117 
    118 func precedence(kind lexer.Kind) int {
    119 	switch kind {
    120 	case lexer.Plus, lexer.Minus:
    121 		return 10
    122 	case lexer.Star, lexer.Slash:
    123 		return 20
    124 	default:
    125 		return -1
    126 	}
    127 }
    128 
    129 func (p *Parser) peek() lexer.Token {
    130 
    131 	if p.pos >= len(p.tokens) {
    132 		return p.tokens[len(p.tokens)-1]
    133 	}
    134 
    135 	return p.tokens[p.pos]
    136 }
    137 
    138 func (p *Parser) advance() lexer.Token {
    139 
    140 	tok := p.peek()
    141 	if p.pos < len(p.tokens) {
    142 		p.pos++
    143 	}
    144 	return tok
    145 }
    146 
    147 func (p *Parser) check(kind lexer.Kind) bool {
    148 	return p.peek().Kind == kind
    149 }
    150 
    151 func (p *Parser) match(kind lexer.Kind) bool {
    152 	if !p.check(kind) {
    153 		return false
    154 	}
    155 	p.advance()
    156 	return true
    157 }
    158 
    159 func (p *Parser) expect(kind lexer.Kind, msg string) lexer.Token {
    160 	if p.check(kind) {
    161 		return p.advance()
    162 	}
    163 
    164 	p.err(p.peek(), msg)
    165 	return lexer.Token{Kind: kind}
    166 }
    167 
    168 func (p *Parser) err(tok lexer.Token, msg string) {
    169 	p.errs = append(p.errs, fmt.Errorf("%d:%d %s", tok.Line, tok.Col, msg))
    170 }
    171 
    172 //
    173 //
    174 //
    175 //
    176 //
    177 //
    178 //
    179 //
    180 //