func createOutputTag(p *core.Parser, isUnsafe bool) (core.Executable, error) { value, err := p.ReadValue() if err != nil { return nil, err } if err = p.ReadCloseTag(); err != nil { return nil, err } return &OutputTag{value, !isUnsafe}, nil }
func ContentFactory(p *core.Parser) (core.Code, error) { value, err := p.ReadValue() if err != nil { return nil, err } if p.SkipSpaces() != '{' { return nil, p.Error("Missing openening brace for content statement") } p.Next() return &ContentCode{new(core.NormalContainer), value}, nil }
func ForFactory(p *core.Parser) (core.Code, error) { if p.TagContains(';') { return ExplicitForFactory(p) } if p.SkipSpaces() == '{' { p.Next() return &ForCode{NormalContainer: new(core.NormalContainer)}, nil } return RangedForFactory(p) }
func createCodeTag(p *core.Parser) (*core.Codes, error) { codes := make([]core.Code, 0, 1) for { token, err := p.ReadToken() if err != nil { return nil, err } length := len(token) if length == 0 { if err := p.ReadCloseTag(); err != nil { return nil, err } return nil, nil } var code core.Code if token == "}" { if p.SkipSpaces() == 'e' && p.ConsumeIf(elseBytes) { code, err = ElseFactory(p) } else { code = endScope } } else if factory, ok := CodeFactories[token]; ok { code, err = factory(p) } else { p.Backwards(length) code, err = p.ReadAssignment() } if err != nil { return nil, err } codes = append(codes, code) if p.SkipSpaces() == '%' { if p.ConsumeIf(trimCloseBytes) { return &core.Codes{true, codes}, nil } if p.ConsumeIf(closeBytes) { return &core.Codes{false, codes}, nil } } } }
func ElseFactory(p *core.Parser) (core.Code, error) { code := &ElseCode{NormalContainer: new(core.NormalContainer)} if p.SkipSpaces() == 'i' && p.ConsumeIf([]byte("if")) { if p.TagContains(';') { assignment, err := p.ReadAssignment() if err != nil { return nil, err } code.assignment = assignment if p.SkipSpaces() != ';' { return nil, p.Error("else if assignment should be followed by a semicolon") } p.Next() } verifiable, err := p.ReadConditionGroup(false) if err != nil { return nil, err } code.verifiable = verifiable if p.SkipSpaces() != '{' { return nil, p.Error("Missing openening brace for else if statement") } } else { code.verifiable = core.TrueCondition //else case if p.SkipSpaces() != '{' { return nil, p.Error("Missing openening brace for else statement") } } p.Next() return code, nil }
func IfFactory(p *core.Parser) (core.Code, error) { code := &IfCode{ NormalContainer: new(core.NormalContainer), assignments: make([]*core.Assignment, 0, 3), verifiables: make([]core.Verifiable, 0, 3), codes: make([]core.Code, 0, 3), } if p.TagContains(';') { assignment, err := p.ReadAssignment() if err != nil { return nil, err } code.assignments = append(code.assignments, assignment) if p.SkipSpaces() != ';' { return nil, p.Error("If assignment should be followed by a semicolon") } p.Next() } else { code.assignments = append(code.assignments, nil) } verifiable, err := p.ReadConditionGroup(false) if err != nil { return nil, err } code.verifiables = append(code.verifiables, verifiable) code.codes = append(code.codes, code) if p.SkipSpaces() != '{' { return nil, p.Error("Missing openening brace for if statement") } p.Next() return code, nil }
func RangedForFactory(p *core.Parser) (core.Code, error) { code := &RangedForCode{NormalContainer: new(core.NormalContainer)} tokens, err := p.ReadTokenList() if err != nil { return nil, err } if len(tokens) != 2 { return nil, p.Error("Invalid for loop, ranged loop should have two variables") } code.tokens = tokens c := p.SkipSpaces() if c == ':' { c = p.Next() } if c != '=' { return nil, p.Error("Invalid for loop, ranged loop expecting assignment operator") } p.Next() if p.SkipSpaces() != 'r' || p.ConsumeIf([]byte("range")) == false { return nil, p.Error("invalid for loop, expected 'range' keyword") } value, err := p.ReadValue() if err != nil { return nil, err } code.value = value if p.SkipSpaces() != '{' { return nil, p.Error("Missing openening brace for if statement") } p.Next() return code, nil }
func ExplicitForFactory(p *core.Parser) (core.Code, error) { code := &ForCode{NormalContainer: new(core.NormalContainer)} if p.SkipSpaces() != ';' { assignment, err := p.ReadAssignment() if err != nil { return nil, err } code.init = assignment } if p.SkipSpaces() != ';' { return nil, p.Error("Invalid for loop, expecting INIT; CONDITION; STEP (1)") } p.Next() verifiable, err := p.ReadConditionGroup(false) if err != nil { return nil, err } code.verifiable = verifiable if p.SkipSpaces() != ';' { return nil, p.Error("Invalid for loop, expecting INIT; CONDITION; STEP (1)") } p.Next() if p.SkipSpaces() != '{' { value, err := p.ReadAssignment() if err != nil { return nil, err } code.step = value } if p.SkipSpaces() != '{' { return nil, p.Error("Missing openening brace for for statement") } p.Next() return code, nil }