Ejemplo n.º 1
0
func TestInstantiation(t *testing.T) {
	testStr := `<?
  $obj = new Obj::$classes['obj']($arg);`
	p := NewParser(testStr)
	a, errs := p.Parse()
	if len(errs) != 0 {
		t.Fatalf("Did not parse instantiation correctly: %s", errs)
	}
	tree := ast.ExpressionStmt{ast.AssignmentExpression{
		Operator: "=",
		Assignee: ast.NewVariable("obj"),
		Value: &ast.NewExpression{
			Class: ast.NewClassExpression("Obj", &ast.ArrayLookupExpression{
				Array: ast.NewVariable("classes"),
				Index: &ast.Literal{Type: ast.String, Value: `'obj'`},
			}),
			Arguments: []ast.Expression{
				ast.NewVariable("arg"),
			},
		},
	}}
	if !assertEquals(a[0], tree) {
		t.Fatalf("Instantiation did not parse correctly")
	}
}
Ejemplo n.º 2
0
func (p *Parser) parseIdentifier() (expr ast.Expr) {
	switch typ := p.peek().Typ; {
	case typ == token.OpenParen && !p.instantiation:
		// Function calls are okay here because we know they came with
		// a non-dynamic identifier.
		expr = p.parseFunctionCall(&ast.Identifier{Value: p.current.Val})
		p.next()
	case typ == token.ScopeResolutionOperator:
		classIdent := p.current.Val
		p.next() // get onto ::, then we get to the next expr
		p.next()
		expr = ast.NewClassExpression(classIdent, p.parseOperand())
		p.next()
	case p.instantiation:
		defer p.next()
		return &ast.Identifier{Value: p.current.Val}
	default:
		name := p.current.Val
		v := ast.NewVariable(p.current.Val)
		expr = ast.ConstantExpr{
			Variable: v,
		}
		p.namespace.Constants[name] = append(p.namespace.Constants[name], v)
		p.next()
	}
	return expr
}
Ejemplo n.º 3
0
// parseScopeResolutionFromKeyword specifically parses self::, static::, and parent::
func (p *Parser) parseScopeResolutionFromKeyword() ast.Expr {
	if p.peek().Typ == token.ScopeResolutionOperator {
		r := p.current.Val
		p.expect(token.ScopeResolutionOperator)
		p.next()
		expr := ast.NewClassExpression(r, p.parseOperand())
		p.next()
		return expr
	}
	// TODO Error
	p.next()
	return nil
}
Ejemplo n.º 4
0
func (p *Parser) parseIdentifier() (expr ast.Expression) {
	switch p.peek().typ {
	case token.OpenParen:
		// Function calls are okay here because we know they came with
		// a non-dynamic identifier.
		expr = p.parseFunctionCall(ast.Identifier{Value: p.current.val})
		p.next()
	case token.ScopeResolutionOperator:
		classIdent := p.current.val
		p.next() // get onto ::, then we get to the next expr
		p.next()
		expr = ast.NewClassExpression(classIdent, p.parseOperand())
		p.next()
	default:
		expr = ast.ConstantExpression{
			Variable: ast.NewVariable(p.current.val),
		}
		p.next()
	}
	return expr
}