Beispiel #1
0
func (p *Parser) parseClass() *ast.Class {
	if p.current.Typ == token.Abstract {
		p.expect(token.Class)
	}
	if p.current.Typ == token.Final {
		p.expect(token.Class)
	}
	switch p.next(); {
	case p.current.Typ == token.Identifier:
	case lexer.IsKeyword(p.current.Typ, p.current.Val):
	default:
		p.errorf("unexpected variable operand %s", p.current)
	}

	name := p.current.Val
	if p.peek().Typ == token.Extends {
		p.expect(token.Extends)
		p.expect(token.Identifier)
	}
	if p.peek().Typ == token.Implements {
		p.expect(token.Implements)
		p.expect(token.Identifier)
		for p.peek().Typ == token.Comma {
			p.expect(token.Comma)
			p.expect(token.Identifier)
		}
	}
	p.expect(token.BlockBegin)
	c := p.parseClassFields(&ast.Class{Name: name})
	p.namespace.ClassesAndInterfaces[c.Name] = c
	return c
}
Beispiel #2
0
func (p *Parser) parseFunctionDefinition() *ast.FunctionDefinition {
	def := &ast.FunctionDefinition{}
	if p.peek().Typ == token.AmpersandOperator {
		// This is a function returning a reference ... ignore this for now
		p.next()
	}
	if !p.accept(token.Identifier) {
		p.next()
		if !lexer.IsKeyword(p.current.Typ, p.current.Val) {
			p.errorf("bad function name: %s", p.current.Val)
		}
	}
	def.Name = p.current.Val
	def.Arguments = make([]*ast.FunctionArgument, 0)
	p.expect(token.OpenParen)
	if p.peek().Typ == token.CloseParen {
		p.expect(token.CloseParen)
		return def
	}
	def.Arguments = append(def.Arguments, p.parseFunctionArgument())
	for {
		switch p.peek().Typ {
		case token.Comma:
			p.expect(token.Comma)
			def.Arguments = append(def.Arguments, p.parseFunctionArgument())
		case token.CloseParen:
			p.expect(token.CloseParen)
			return def
		default:
			p.errorf("unexpected argument separator: %s", p.current)
			return def
		}
	}
}
Beispiel #3
0
func (p *Parser) parseVariable() ast.Expr {
	var expr *ast.Variable
	p.expectCurrent(token.VariableOperator)
	switch p.next(); {
	case lexer.IsKeyword(p.current.Typ, p.current.Val):
		// keywords are all valid variable names
		fallthrough
	case p.current.Typ == token.Identifier:
		expr = ast.NewVariable(p.current.Val)
	case p.current.Typ == token.BlockBegin:
		expr = &ast.Variable{Name: p.parseNextExpression()}
		p.expect(token.BlockEnd)
	case p.current.Typ == token.VariableOperator:
		expr = &ast.Variable{Name: p.parseVariable()}
	default:
		p.errorf("unexpected variable operand %s", p.current)
		return nil
	}

	p.scope.Variable(expr)
	return expr
}