diff --git a/examples/rule110.mcl b/examples/rule110.mcl index f5442ad..4cec46f 100755 --- a/examples/rule110.mcl +++ b/examples/rule110.mcl @@ -1,5 +1,4 @@ - -macro puts 1 1 syscall3 drop end +include "io.mcl" macro BOARD_SIZE 100 end @@ -8,14 +7,14 @@ mem BOARD_SIZE 2 - + 1 @8 0 while dup BOARD_SIZE 2 - < do 0 while dup BOARD_SIZE < do dup mem + !8 if - dup mem + BOARD_SIZE + 42 @8 + dup mem + BOARD_SIZE + '*' @8 else - dup mem + BOARD_SIZE + 32 @8 + dup mem + BOARD_SIZE + ' ' @8 end 1 + end - mem + BOARD_SIZE + 10 @8 + mem + BOARD_SIZE + '\n' @8 BOARD_SIZE 1 + mem BOARD_SIZE + puts diff --git a/src/constants.rs b/src/constants.rs index 9b333b3..5d511cf 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -140,7 +140,7 @@ pub enum TokenType { Word, Int, String, - //TODO: Add char + Char } impl Token { @@ -159,6 +159,7 @@ impl TokenType { TokenType::Word => "Word", TokenType::Int => "Int", TokenType::String => "String", + TokenType::Char => "Char" }.to_string() } } diff --git a/src/lexer.rs b/src/lexer.rs index 623cc6c..a2aae5c 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -11,9 +11,12 @@ fn lex_word(s: String, tok_type: TokenType) -> (TokenType, String) { return (TokenType::Word, s); }, s if tok_type == TokenType::String => { - return (tok_type, s); + return (TokenType::String, s); } - _ => panic!() + s if tok_type == TokenType::Char=> { + return (TokenType::Char, s); + } + _ => unreachable!() } } @@ -52,6 +55,22 @@ fn lex_line(text: String) -> Result> { } col = find_col(text.clone(), col_end + 1, |x, _| !x.is_whitespace())?; + } else if &text[(col as usize)..(col + 1) as usize] == "'"{ + col_end = find_col(text.clone(), col + 1, |x, x2| x == '\'' && x2 != '\\')?; + let t = &text[((col + 1) as usize)..(col_end as usize)]; + let t = t.replace("\\n", "\n") + .replace("\\t", "\t") + .replace("\\r", "\r") + .replace("\\\'", "\'") + .replace("\\\"", "\"") + .replace("\\0", "\0"); + + + if !t.is_empty() { + tokens.push((col, t.to_string(), TokenType::Char)); + } + col = find_col(text.clone(), col_end + 1, |x, _| !x.is_whitespace())?; + } else { col_end = find_col(text.clone(), col, |x, _| x.is_whitespace())?; diff --git a/src/parser.rs b/src/parser.rs index 7ddc525..dffa457 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -92,6 +92,15 @@ impl Parser { TokenType::String => { tokens.push(Operator::new(OpType::PushStr, 0, token.text.clone(), token.file.clone(), token.line, token.col)); } + TokenType::Char => { + let c = token.text.clone(); + if c.len() != 1 { + lerror!(&token.loc(), "Chars can only be of lenght 1, got {}", c.len()); + return Err(eyre!("")); + } + + tokens.push(Operator::new(OpType::PushInt, token.text.chars().next().unwrap() as i64, String::new(), token.file.clone(), token.line, token.col)); + } }; diff --git a/test.mcl b/test.mcl index a54b606..1613b36 100644 --- a/test.mcl +++ b/test.mcl @@ -1,6 +1 @@ -include "io.mcl" -include "util.mcl" - -"HEnlo world!\n" puts - -2 2 = "i suck at math" assert \ No newline at end of file +' ' print \ No newline at end of file