Skip to content

Commit

Permalink
⚔️ added lexer errors
Browse files Browse the repository at this point in the history
  • Loading branch information
aym-n committed Jan 11, 2024
1 parent b1120cb commit 86db225
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 70 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "arc"
version = "0.1.0"
version = "1.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
10 changes: 1 addition & 9 deletions main.arc
Original file line number Diff line number Diff line change
@@ -1,9 +1 @@
class Doughnut {
cook() {
print "Fry until golden brown.";
}
}

class BostonCream < Doughnut {}

BostonCream().cook();
print "hello;
14 changes: 14 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,24 @@ use crate::tokens::*;

#[derive(Debug, PartialEq, Clone)]
pub enum Error {
LexerError{ lexeme: String , line: String, message: String},
ParseError { token: Token, message: String },
RuntimeError { token: Token, message: String },
SystemError { message: String },
Return { value: Object },
}

impl Error {
pub fn lexer_error(lexeme: &str, line: &str, message: &str) -> Error {
let err = Error::LexerError {
lexeme: lexeme.to_string(),
line: line.to_string(),
message: message.to_string(),
};
err.report("");
err
}

pub fn return_value(value: Object) -> Error {
Error::Return { value }
}
Expand Down Expand Up @@ -41,6 +52,9 @@ impl Error {

pub fn report(&self, _loc: &str) {
match self {
Error::LexerError { lexeme, line, message } => {
eprintln!("[line {}] Error {}: {}", line, lexeme, message);
}
Error::ParseError { token, message }
| Error::RuntimeError { token, message } => {
if token.kind == TokenKind::EOF {
Expand Down
24 changes: 20 additions & 4 deletions src/lexer.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::tokens::*;

use crate::errors::*;
pub struct Lexer {
input: String,
start: usize,
current: usize,
line: usize,
pub had_error: bool,
}

impl Lexer {
Expand All @@ -14,6 +15,7 @@ impl Lexer {
start: 0,
current: 0,
line: 1,
had_error: false,
}
}

Expand Down Expand Up @@ -73,7 +75,12 @@ impl Lexer {
}

if self.is_at_end() {
eprintln!("{}: Unterminated string.", self.line);
Error::lexer_error(
&self.input[self.start..self.current].to_string(),
&self.line.to_string(),
"unterminated string.",
);
self.had_error = true;
return None;
}

Expand Down Expand Up @@ -105,9 +112,13 @@ impl Lexer {
fn is_at_end(&self) -> bool {
self.current > self.input.len() - 1
}

pub fn success(&self) -> bool {
!self.had_error
}
}

impl Iterator for Lexer {
impl<'a> Iterator for &'a mut Lexer {
type Item = Token;
fn next(&mut self) -> Option<Self::Item> {
if self.is_at_end() {
Expand Down Expand Up @@ -212,7 +223,12 @@ impl Iterator for Lexer {
}

_ => {
eprintln!("{}: Unexpected character: {}", self.line, self.current_char());
Error::lexer_error(
&self.input[self.start..self.current].to_string(),
&self.line.to_string(),
"unexpected character.",
);
self.had_error = true;
None
}
}
Expand Down
110 changes: 55 additions & 55 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,55 +1,41 @@
use std::io::Write;

mod lexer;
use crate::lexer::Lexer;

mod tokens;
use tokens::*;

mod callable;
mod enviroment;
mod errors;
use crate::errors::*;

// mod ast_printer;
// use crate::ast_printer::AstPrinter;

mod expr;

mod parser;
use parser::*;

mod functions;
mod instance;
mod interpreter;
use interpreter::Interpreter;

mod stmt;

mod enviroment;

mod callable;

mod lexer;
mod native_functions;

mod functions;

mod parser;
mod resolver;
use resolver::*;
mod stmt;
mod tokens;

use crate::errors::*;
use crate::lexer::Lexer;
use interpreter::Interpreter;
use parser::*;
use resolver::*;
use std::io::Write;
use std::rc::Rc;

mod instance;
use tokens::*;

fn eval(source: &str) -> Result<(), Error> {
let lexer = Lexer::new(source.to_string());
let mut lexer = Lexer::new(source.to_string());
let tokens: Vec<Token> = lexer.collect();

let mut parser = Parser::new(tokens);
let statements = parser.parse();
if lexer.success() {
let mut parser = Parser::new(tokens);
let statements = parser.parse();

let interpreter = Interpreter::new();
let s = Rc::new(statements?);
let resolver = Resolver::new(&interpreter);
resolver.resolve(&Rc::clone(&s));
if resolver.success(){
interpreter.interpret(&Rc::clone(&s));
let interpreter = Interpreter::new();
let s = Rc::new(statements?);
let resolver = Resolver::new(&interpreter);
resolver.resolve(&Rc::clone(&s));
if resolver.success() {
interpreter.interpret(&Rc::clone(&s));
}
}
Ok(())
}
Expand All @@ -58,34 +44,48 @@ fn repl() {
let interpreter = Interpreter::new();
loop {
let mut input = String::new();
print!(">");
//ascii header
println!(
r#"
█████╗ ██████╗ ██████╗
██╔══██╗██╔══██╗██╔════╝
███████║██████╔╝██║
██╔══██║██╔══██╗██║
██║ ██║██║ ██║╚██████╗
╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝
[v1.1.0]
"#
);
print!("arc~> ");
std::io::stdout().flush().unwrap();
std::io::stdin().read_line(&mut input).unwrap();

input = input.trim_end_matches('\n').to_string();
match input.trim() {
"exit" => std::process::exit(0),
"clear" => print!("{}[2J", 27 as char),
"@" => interpreter.print_env(),
_ => {
let lexer = Lexer::new(input);
let mut lexer = Lexer::new(input);
let tokens: Vec<Token> = lexer.collect();

let mut parser = Parser::new(tokens);
let statements = parser.parse();
if lexer.success() {
let mut parser = Parser::new(tokens);
let statements = parser.parse();

match statements {
Ok(statements) => {
let s = Rc::new(statements);
let resolver = Resolver::new(&interpreter);
resolver.resolve(&Rc::clone(&s));
match statements {
Ok(statements) => {
let s = Rc::new(statements);
let resolver = Resolver::new(&interpreter);
resolver.resolve(&Rc::clone(&s));

if resolver.success() {
if !interpreter.interpret(&Rc::clone(&s)) {
std::process::exit(1);
if resolver.success() {
if !interpreter.interpret(&Rc::clone(&s)) {
std::process::exit(1);
}
}
}

Err(_) => std::process::exit(2),
}
Err(_) => std::process::exit(2),
}
}
}
Expand Down

0 comments on commit 86db225

Please sign in to comment.