From f6548019e308e11bab732d211c4be2b9566aefc4 Mon Sep 17 00:00:00 2001 From: Sofia Date: Tue, 17 Mar 2026 21:05:51 +0200 Subject: [PATCH] Add keywords nil, true, false --- examples/test.lua | 3 ++- src/ast.rs | 9 +++++++++ src/compile.rs | 14 +++++++++++++- src/token_stream/lexer.rs | 12 ++++++++++++ src/vm.rs | 6 ++++++ 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/examples/test.lua b/examples/test.lua index 661bd90..ebaa6be 100644 --- a/examples/test.lua +++ b/examples/test.lua @@ -26,4 +26,5 @@ print(add(10)(15)) print(b) print(min(11, 9)) print(10 - 15) -print("hello there!") \ No newline at end of file +print("hello there!") +print(nil or 0) \ No newline at end of file diff --git a/src/ast.rs b/src/ast.rs index f4b05b9..d0023d0 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -471,6 +471,13 @@ impl Parse for PrimaryExpression { } else if let Some(Token::StringLit(value)) = peeked { stream.next(); // Consume string-literal Expression::Literal(Literal::String(value)) + } else if let Some(Token::Keyword(Keyword::True) | Token::Keyword(Keyword::False)) = peeked + { + let value = Token::Keyword(Keyword::True) == stream.next().unwrap(); + Expression::Literal(Literal::Bool(value)) + } else if let Some(Token::Keyword(Keyword::Nil)) = peeked { + stream.next(); // Consume nil + Expression::Literal(Literal::Nil) } else if let Some(Token::Symbol('{')) = peeked { stream.next(); stream.expect_symbol('}')?; @@ -556,4 +563,6 @@ pub enum Literal { Float(LuaFloat), Integer(LuaInteger), String(String), + Bool(bool), + Nil, } diff --git a/src/compile.rs b/src/compile.rs index 55471db..7231ec8 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet}; use crate::{ ast::{AccessModifier, BinaryOperator, Block, Expression, Literal, Statement, UnaryOperator}, - vm::{Constant, Instruction, VMFloat}, + vm::{Constant, Instruction, LuaBool, VMFloat}, }; pub struct State { @@ -386,6 +386,16 @@ impl Expression { constants.insert(Constant::String(value.clone())); constants } + Literal::Bool(value) => { + let mut constants = HashSet::new(); + constants.insert(Constant::Bool(LuaBool(*value))); + constants + } + Literal::Nil => { + let mut constants = HashSet::new(); + constants.insert(Constant::Nil); + constants + } }, Expression::TableConstructor => { let constants = HashSet::new(); @@ -604,6 +614,8 @@ impl Expression { Literal::Float(value) => Constant::Float(value.vm_number()), Literal::String(value) => Constant::String(value.clone()), Literal::Integer(lua_integer) => Constant::Integer(*lua_integer), + Literal::Bool(value) => Constant::Bool(LuaBool(*value)), + Literal::Nil => Constant::Nil, }), )); (instructions, vec![reg]) diff --git a/src/token_stream/lexer.rs b/src/token_stream/lexer.rs index 5e8a143..a07bb50 100644 --- a/src/token_stream/lexer.rs +++ b/src/token_stream/lexer.rs @@ -16,6 +16,10 @@ pub enum Keyword { Return, If, Then, + True, + False, + Nil, + Not, } impl Keyword { @@ -28,6 +32,10 @@ impl Keyword { "return" => Keyword::Return, "if" => Keyword::If, "then" => Keyword::Then, + "true" => Keyword::True, + "false" => Keyword::False, + "nil" => Keyword::Nil, + "not" => Keyword::Not, _ => None?, }) } @@ -43,6 +51,10 @@ impl ToString for Keyword { Keyword::Return => "return", Keyword::If => "if", Keyword::Then => "then", + Keyword::True => "true", + Keyword::False => "false", + Keyword::Nil => "nil", + Keyword::Not => "not", } .to_string() } diff --git a/src/vm.rs b/src/vm.rs index 33a3252..852657c 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -90,6 +90,8 @@ pub enum Constant { String(String), Float(VMFloat), Integer(LuaInteger), + Bool(LuaBool), + Nil, } impl Debug for Constant { @@ -98,6 +100,8 @@ impl Debug for Constant { Self::String(arg0) => f.debug_tuple("String").field(arg0).finish(), Self::Float(arg0) => f.debug_tuple("Number").field(&arg0.lua_number()).finish(), Self::Integer(arg0) => f.debug_tuple("Integer").field(arg0).finish(), + Self::Bool(arg0) => f.debug_tuple("Boolean").field(arg0).finish(), + Self::Nil => f.debug_tuple("Nil").finish(), } } } @@ -657,6 +661,8 @@ impl ClosureRunner { Constant::String(value) => Value::String(value.clone()), Constant::Float(value) => Value::Float(*value), Constant::Integer(value) => Value::Integer(*value), + Constant::Bool(lua_bool) => Value::Boolean(*lua_bool), + Constant::Nil => Value::Nil, }), ); }