Skip to content

Commit

Permalink
Handle none
Browse files Browse the repository at this point in the history
  • Loading branch information
DePasqualeOrg committed Oct 1, 2024
1 parent 2ea5ad3 commit 0a4d414
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 11 deletions.
4 changes: 4 additions & 0 deletions Sources/Ast.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,7 @@ struct KeywordArgumentExpression: Expression {
var key: Identifier
var value: any Expression
}

struct NullLiteral: Literal {
var value: Any? = nil
}
6 changes: 5 additions & 1 deletion Sources/Environment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,17 @@ class Environment {
}

return ObjectValue(value: object)
case is NullValue:
return NullValue()
case Optional<Any>.none:
return NullValue()
default:
throw JinjaError.runtime("Cannot convert to runtime value: \(input) type:\(type(of: input))")
}
}

@discardableResult
func set(name: String, value: Any) throws -> any RuntimeValue {
func set(name: String, value: Any?) throws -> any RuntimeValue {
try self.declareVariable(name: name, value: self.convertToRuntimeValues(input: value))
}

Expand Down
3 changes: 3 additions & 0 deletions Sources/Lexer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ enum TokenType: String {
case numericLiteral = "NumericLiteral"
case booleanLiteral = "BooleanLiteral"
case stringLiteral = "StringLiteral"
case nullLiteral = "NullLiteral"
case identifier = "Identifier"
case equals = "Equals"
case openParen = "OpenParen"
Expand Down Expand Up @@ -71,6 +72,8 @@ let keywords: [String: TokenType] = [
"not": .not,
"true": .booleanLiteral,
"false": .booleanLiteral,
"none": .nullLiteral,
"None": .nullLiteral,
]

func isWord(char: String) -> Bool {
Expand Down
16 changes: 8 additions & 8 deletions Sources/Parser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -187,21 +187,18 @@ func parse(tokens: [Token]) throws -> Program {
while typeof(.is) {
current += 1
let negate = typeof(.not)

if negate {
current += 1
}

var filter = try parsePrimaryExpression()

if let boolLiteralFlter = filter as? BoolLiteral {
filter = Identifier(value: String(boolLiteralFlter.value))
if let boolLiteralFilter = filter as? BoolLiteral {
filter = Identifier(value: String(boolLiteralFilter.value))
} else if let nullLiteralFilter = filter as? NullLiteral {
filter = Identifier(value: "none")
}

if let test = filter as? Identifier {
operand = TestExpression(operand: operand as! Expression, negate: negate, test: test)
}
else {
} else {
throw JinjaError.syntax("Expected identifier for the test")
}
}
Expand Down Expand Up @@ -415,6 +412,9 @@ func parse(tokens: [Token]) throws -> Program {
current += 1

return ObjectLiteral(value: values)
case .nullLiteral:
current += 1
return NullLiteral()
default:
throw JinjaError.syntax("Unexpected token: \(token.type)")
}
Expand Down
6 changes: 4 additions & 2 deletions Sources/Runtime.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ struct BooleanValue: RuntimeValue {
}

struct NullValue: RuntimeValue {
var value: (any RuntimeValue)?
var value: Any? = nil
var builtins: [String: any RuntimeValue] = [:]

func bool() -> Bool {
Expand Down Expand Up @@ -693,8 +693,10 @@ struct Interpreter {
return BooleanValue(value: statement.value)
case let statement as FilterExpression:
return try self.evaluateFilterExpression(node: statement, environment: environment)
case is NullLiteral:
return NullValue()
default:
throw JinjaError.runtime("Unknown node type: \(type(of:statement))")
throw JinjaError.runtime("Unknown node type: \(type(of:statement)), statement: \(String(describing: statement))")
}
}
else {
Expand Down
1 change: 1 addition & 0 deletions Sources/Template.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public struct Template {

try env.set(name: "false", value: false)
try env.set(name: "true", value: true)
try env.set(name: "none", value: NullValue())
try env.set(
name: "raise_exception",
value: { (args: String) throws in
Expand Down

0 comments on commit 0a4d414

Please sign in to comment.