summaryrefslogtreecommitdiff
path: root/axisc/src/lexer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'axisc/src/lexer.rs')
-rw-r--r--axisc/src/lexer.rs134
1 files changed, 127 insertions, 7 deletions
diff --git a/axisc/src/lexer.rs b/axisc/src/lexer.rs
index ff13fd3..49913a4 100644
--- a/axisc/src/lexer.rs
+++ b/axisc/src/lexer.rs
@@ -1,11 +1,24 @@
+use std::fmt;
+use crate::error::{CompileError, ErrorHint, ErrorHints, raise_error};
use crate::reader::TokenScanner;
#[derive(Debug)]
-pub enum Token {
+pub enum TokenKind {
Identifier(String),
Keyword(Keyword),
Literal(Literal),
- SimpleToken(SimpleToken)
+ Simple(SimpleToken)
+}
+
+impl fmt::Display for TokenKind {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ TokenKind::Identifier(s) => write!(f, "`{}`", s),
+ TokenKind::Keyword(k) => write!(f, "{:?}", k),
+ TokenKind::Literal(l) => write!(f, "{}", l),
+ TokenKind::Simple(t) => write!(f, "{}", t)
+ }
+ }
}
#[derive(Debug)]
@@ -43,12 +56,39 @@ pub enum SimpleToken {
Caret,
Dollar,
Equals,
+ DoubleEquals,
Semicolon,
GreaterThan,
LessThan,
Add,
Subtract,
LineFeed,
+ Comment,
+ Arrow
+}
+
+impl fmt::Display for SimpleToken {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ SimpleToken::Multiply => write!(f, "multiply"),
+ SimpleToken::Divide => write!(f, "divide"),
+ SimpleToken::Pound => write!(f, "pound"),
+ SimpleToken::Colon => write!(f, "colon"),
+ SimpleToken::Percent => write!(f, "percent"),
+ SimpleToken::Caret => write!(f, "caret"),
+ SimpleToken::Dollar => write!(f, "dollar"),
+ SimpleToken::Equals => write!(f, "equals"),
+ SimpleToken::DoubleEquals => write!(f, "double equals"),
+ SimpleToken::Semicolon => write!(f, "semicolon"),
+ SimpleToken::GreaterThan => write!(f, "greater than"),
+ SimpleToken::LessThan => write!(f, "less than"),
+ SimpleToken::Add => write!(f, "plus"),
+ SimpleToken::Subtract => write!(f, "minus "),
+ SimpleToken::LineFeed => write!(f, "line break"),
+ SimpleToken::Comment => write!(f, "comment"),
+ SimpleToken::Arrow => write!(f, "arrow"),
+ }
+ }
}
#[derive(Debug)]
@@ -59,6 +99,17 @@ pub enum Literal {
Array(Array)
}
+impl fmt::Display for Literal {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Literal::String(_) => write!(f, "string"),
+ Literal::Number(_) => write!(f, "number"),
+ Literal::Boolean(_) => write!(f, "boolean"),
+ Literal::Array(a) => write!(f, "{}", a),
+ }
+ }
+}
+
#[derive(Debug)]
pub enum Keyword {
Into,
@@ -68,29 +119,98 @@ pub enum Keyword {
String,
As,
Let,
+ Free,
+ Derive,
+ Checkpoint,
+ Subroutine,
+ GoTo,
+ AsFn,
+ If,
+ Then,
+ Else,
+ And,
+ Or,
+ Xor,
+ Not,
+ For,
+ To,
+ Next,
+ While,
+ Forever,
+ Repeat,
}
#[derive(Debug)]
pub enum Array {
- StringArray(Vec<String>),
- NumberArray(Vec<f64>),
- BooleanArray(Vec<bool>),
- MultiDimensionalArray(Vec<Array>)
+ String(Vec<String>),
+ Number(Vec<f64>),
+ Boolean(Vec<bool>),
+ MultiDimensional(Vec<Array>)
+}
+
+impl fmt::Display for Array {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Array::String(_) => write!(f, "string array"),
+ Array::Number(_) => write!(f, "number array"),
+ Array::Boolean(_) => write!(f, "boolean array"),
+ Array::MultiDimensional(_) => write!(f, "multi-dimensional array"),
+ }
+ }
}
impl Literal {
pub fn string_literal_from_scanner(token_scanner: &mut TokenScanner) -> Literal {
token_scanner.advance(1);
+
+ let start_position = TokenPosition::from_scanner(token_scanner);
+ let start_position_hint = ErrorHint::new(start_position, "string starts here");
+ let start_position_hints = ErrorHints::from(vec![start_position_hint]);
+
let mut string = String::new();
loop {
match token_scanner.advance(1) {
Some('"') => break,
+ Some('\n') => raise_error(token_scanner, CompileError::UnexpectedStringLineBreak, Some("line break occurs here"), Some(start_position_hints), Some("strings are wrapped in \"double quotes\"")),
Some(c) => string.push(c),
- None => todo!("Reached EOF before end of string")
+ None => raise_error(token_scanner, CompileError::UnexpectedStringEOF, Some("file ends here"), Some(start_position_hints), Some("strings are wrapped in \"double quotes\"")),
}
}
Literal::String(string)
}
}
+
+#[derive(Debug)]
+pub struct Token {
+ position: TokenPosition,
+ token: TokenKind
+}
+
+impl Token {
+ pub fn new(position: (usize, usize), token: TokenKind) -> Self {
+ Self {
+ position: TokenPosition {
+ line: position.0,
+ column: position.1
+ },
+ token
+ }
+ }
+}
+
+#[derive(Debug)]
+pub struct TokenPosition {
+ pub line: usize,
+ pub column: usize
+}
+
+impl TokenPosition {
+ pub fn from_scanner(token_scanner: &TokenScanner) -> Self {
+ Self {
+ line: token_scanner.line,
+ column: token_scanner.column
+ }
+ }
+}