Add nil keyword
This commit is contained in:
parent
f1a998c25b
commit
d5c33f9e5d
@ -20,6 +20,14 @@ func (p Position) String() string {
|
|||||||
return fmt.Sprintf("%s: line %d, col %d", p.Name, p.Line, p.Col)
|
return fmt.Sprintf("%s: line %d, col %d", p.Name, p.Line, p.Col)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Nil struct {
|
||||||
|
Position Position
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n Nil) Pos() Position {
|
||||||
|
return n.Position
|
||||||
|
}
|
||||||
|
|
||||||
type Tag struct {
|
type Tag struct {
|
||||||
Name Ident
|
Name Ident
|
||||||
Params []Node
|
Params []Node
|
||||||
|
11
expr.go
11
expr.go
@ -54,6 +54,17 @@ func (t *Template) performOp(a, b reflect.Value, op ast.Operator) (any, error) {
|
|||||||
default:
|
default:
|
||||||
return nil, ast.PosError(op, "the in operator can only be used on strings, arrays, and slices (got %s and %s)", a.Type(), b.Type())
|
return nil, ast.PosError(op, "the in operator can only be used on strings, arrays, and slices (got %s and %s)", a.Type(), b.Type())
|
||||||
}
|
}
|
||||||
|
} else if !b.IsValid() {
|
||||||
|
if op.Value != "==" {
|
||||||
|
return nil, ast.PosError(op, "invalid operator for nil value (expected ==, got %s)", op.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch a.Kind() {
|
||||||
|
case reflect.Chan, reflect.Slice, reflect.Map, reflect.Func, reflect.Interface, reflect.Pointer:
|
||||||
|
return a.IsNil(), nil
|
||||||
|
default:
|
||||||
|
return nil, ast.PosError(op, "values of type %s cannot be compared against nil", a.Type())
|
||||||
|
}
|
||||||
} else if b.CanConvert(a.Type()) {
|
} else if b.CanConvert(a.Type()) {
|
||||||
b = b.Convert(a.Type())
|
b = b.Convert(a.Type())
|
||||||
} else {
|
} else {
|
||||||
|
606
parser/parser.go
606
parser/parser.go
File diff suppressed because it is too large
Load Diff
@ -129,7 +129,7 @@ ParamList = '(' params:(Expr ( ',' _ Expr )* )? ')' {
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
Value = not:"!"? node:(MethodCall / FieldAccess / Index / String / RawString / Float / Integer / Bool / FuncCall / VariableOr / Ident / ParenExpr / Array / Map) {
|
Value = not:"!"? node:(Nil / MethodCall / FieldAccess / Index / String / RawString / Float / Integer / Bool / FuncCall / VariableOr / Ident / ParenExpr / Array / Map) {
|
||||||
return ast.Value{
|
return ast.Value{
|
||||||
Node: node.(ast.Node),
|
Node: node.(ast.Node),
|
||||||
Not: not != nil,
|
Not: not != nil,
|
||||||
@ -288,6 +288,10 @@ ArithmeticOp = ('+' / '-' / '/' / '*' / '%') {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Nil = "nil" {
|
||||||
|
return ast.Nil{Position: getPos(c)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
Text = . [^#]* { return ast.Text{Data: c.text, Position: getPos(c)}, nil }
|
Text = . [^#]* { return ast.Text{Data: c.text, Position: getPos(c)}, nil }
|
||||||
|
|
||||||
_ "whitespace" ← [ \t\r\n]*
|
_ "whitespace" ← [ \t\r\n]*
|
||||||
|
2
salix.go
2
salix.go
@ -239,6 +239,8 @@ func (t *Template) getValue(node ast.Node, local map[string]any) (any, error) {
|
|||||||
return t.convertArray(node, local)
|
return t.convertArray(node, local)
|
||||||
case ast.Assignment:
|
case ast.Assignment:
|
||||||
return node, t.handleAssignment(node, local)
|
return node, t.handleAssignment(node, local)
|
||||||
|
case ast.Nil:
|
||||||
|
return nil, nil
|
||||||
default:
|
default:
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user