// 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) }
// 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 }
// 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) }