Beispiel #1
0
// closeBlock : OPEN_ENDBLOCK helperName CLOSE
func (p *parser) parseCloseBlock(block *ast.BlockStatement) {
	// OPEN_ENDBLOCK
	tok := p.shift()
	if tok.Kind != lexer.TokenOpenEndBlock {
		errExpected(lexer.TokenOpenEndBlock, tok)
	}

	// helperName
	endId := p.parseHelperName()

	closeName, ok := ast.HelperNameStr(endId)
	if !ok {
		errNode(endId, "Erroneous closing expression")
	}

	openName := block.Expression.Canonical()
	if openName != closeName {
		errNode(endId, fmt.Sprintf("%s doesn't match %s", openName, closeName))
	}

	// CLOSE
	tokClose := p.shift()
	if tokClose.Kind != lexer.TokenClose {
		errExpected(lexer.TokenClose, tokClose)
	}

	block.CloseStrip = ast.NewStrip(tok.Val, tokClose.Val)
}
Beispiel #2
0
// rawBlock : openRawBlock content endRawBlock
// openRawBlock : OPEN_RAW_BLOCK helperName param* hash? CLOSE_RAW_BLOCK
// endRawBlock : OPEN_END_RAW_BLOCK helperName CLOSE_RAW_BLOCK
func (p *parser) parseRawBlock() *ast.BlockStatement {
	// OPEN_RAW_BLOCK
	tok := p.shift()

	result := ast.NewBlockStatement(tok.Pos, tok.Line)

	// helperName param* hash?
	result.Expression = p.parseExpression(tok)

	openName := result.Expression.Canonical()

	// CLOSE_RAW_BLOCK
	tok = p.shift()
	if tok.Kind != lexer.TokenCloseRawBlock {
		errExpected(lexer.TokenCloseRawBlock, tok)
	}

	// content
	// @todo Is content mandatory in a raw block ?
	content := p.parseContent()

	program := ast.NewProgram(tok.Pos, tok.Line)
	program.AddStatement(content)

	result.Program = program

	// OPEN_END_RAW_BLOCK
	tok = p.shift()
	if tok.Kind != lexer.TokenOpenEndRawBlock {
		// should never happen as it is caught by lexer
		errExpected(lexer.TokenOpenEndRawBlock, tok)
	}

	// helperName
	endId := p.parseHelperName()

	closeName, ok := ast.HelperNameStr(endId)
	if !ok {
		errNode(endId, "Erroneous closing expression")
	}

	if openName != closeName {
		errNode(endId, fmt.Sprintf("%s doesn't match %s", openName, closeName))
	}

	// CLOSE_RAW_BLOCK
	tok = p.shift()
	if tok.Kind != lexer.TokenCloseRawBlock {
		errExpected(lexer.TokenCloseRawBlock, tok)
	}

	return result
}
Beispiel #3
0
// VisitPartial implements corresponding Visitor interface method
func (v *evalVisitor) VisitPartial(node *ast.PartialStatement) interface{} {
	v.at(node)

	// partialName: helperName | sexpr
	name, ok := ast.HelperNameStr(node.Name)
	if !ok {
		if subExpr, ok := node.Name.(*ast.SubExpression); ok {
			name, _ = subExpr.Accept(v).(string)
		}
	}

	if name == "" {
		v.errorf("Unexpected partial name: %q", node.Name)
	}

	partial := v.findPartial(name)
	if partial == nil {
		v.errorf("Partial not found: %s", name)
	}

	return v.evalPartial(partial, node)
}