From d36381bb4ee1a1c5c4bb86aa8804bff3c47b29f3 Mon Sep 17 00:00:00 2001 From: TudbuT Date: Tue, 16 Jan 2024 06:39:38 +0100 Subject: [PATCH] properly implement code tracing --- src/lib.rs | 5 +++++ src/main.rs | 25 +++++++++++++++---------- src/parser.rs | 30 +++++++++++++----------------- src/runtime.rs | 1 + src/tokenizer.rs | 27 +++++++++++++++------------ src/word.rs | 9 ++++++++- std.aea | 2 +- 7 files changed, 58 insertions(+), 41 deletions(-) create mode 100644 src/lib.rs create mode 100644 src/runtime.rs diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..c6d8a32 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,5 @@ +pub mod parser; +pub mod tokenizer; +pub mod ty; +pub mod value; +pub mod word; diff --git a/src/main.rs b/src/main.rs index ec733ce..149a28e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,13 @@ use std::fs; -use crate::{parser::Parser, tokenizer::Tokenizer, value::Value, word::Word}; - -pub mod parser; -pub mod tokenizer; -pub mod ty; -pub mod value; -pub mod word; +use aeapa::{parser::Parser, tokenizer::tokenize, value::Value, word::Word}; fn main() { - let tokens = Tokenizer::tokenize(fs::read_to_string("std.aea").unwrap()).unwrap(); + let tokens = tokenize( + fs::read_to_string("std.aea").unwrap(), + Some("std.aea".to_owned()), + ) + .unwrap(); println!("{tokens:?}"); let words = Parser::parse(&tokens).unwrap(); println!("{words:?}"); @@ -32,8 +30,15 @@ fn main() { println!("{}", stack.pop().unwrap()); } } - Word::Function(name, args, ret, words) => { - println!("If i was an interpreter I would define function {name}({args:?}) {ret:?} {{{words:?}}}") + Word::Function { + name, + args, + rets, + code, + file, + line, + } => { + println!("If i was an interpreter I would define function {name}({args:?}) {rets:?} {{{code:?}}} of {file}:{line}") } _ => todo!(), } diff --git a/src/parser.rs b/src/parser.rs index 55b70e9..b982ca8 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -23,6 +23,7 @@ pub enum ParseError { UnexpectedToken(CodePos, Token, String), ExpectedIdentifierAfterColon(CodePos), ExpectedParen(CodePos), + NeedFileToken, } #[derive(Default)] @@ -34,6 +35,7 @@ struct State { pub struct Parser<'a> { slice: &'a [Token], index: usize, + line: usize, file: Option, } @@ -42,6 +44,7 @@ impl<'a> Parser<'a> { Parser { slice: tokens, index: 0, + line: 0, file: None, } } @@ -92,20 +95,13 @@ impl<'a> Parser<'a> { file: self.file.as_ref().cloned(), char_in_file: None, token: Some(self.index), - line: Some( - self.slice[0..self.index] - .iter() - .filter(|t| matches!(t, Token::Newline(_))) - .count() - + 1, - ), + line: Some(self.line), } } pub fn read_level_at(&mut self, index: usize) -> Result, ParseError> { self.index = index; let mut words = Vec::new(); - let mut file = None; let mut state = State { ..Default::default() @@ -172,11 +168,8 @@ impl<'a> Parser<'a> { state.paren_mode.push(false); } } - Token::Newline(_) => (), - Token::Filename(f) => file = Some(f), - } - if self.file != file { - self.file = file.clone(); + Token::Newline(n) => self.line = n, + Token::Filename(f) => self.file = Some(f), } } Ok(words) @@ -185,6 +178,7 @@ impl<'a> Parser<'a> { fn try_match_keyword(&mut self, ident: &String) -> Result, ParseError> { match ident.as_str() { "fn" => { + let line = self.line; let name = self.next_as_ident()?; self.assert_next_eq(Token::Open)?; let mut arr = Vec::new(); @@ -220,12 +214,14 @@ impl<'a> Parser<'a> { ))?, } } - Ok(Some(Word::Function( + Ok(Some(Word::Function { name, args, - arr, - self.read_level_at(self.index)?, - ))) + rets: arr, + code: self.read_level_at(self.index)?, + file: self.file.as_ref().ok_or(ParseError::NeedFileToken)?.clone(), + line, + })) } "if" => Ok(Some(Word::StartIf)), "while" => Ok(Some(Word::StartWhile)), diff --git a/src/runtime.rs b/src/runtime.rs new file mode 100644 index 0000000..1886cf1 --- /dev/null +++ b/src/runtime.rs @@ -0,0 +1 @@ +pub struct Runtime {} diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 1bad85a..2a4b263 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -7,21 +7,23 @@ use crate::{ word::Token, }; -pub struct Tokenizer<'a> { +struct Tokenizer<'a> { char_iter: Chars<'a>, string: String, + file: String, +} + +pub fn tokenize(string: String, file: Option) -> Result, ParseError> { + let tokenizer = Tokenizer { + // SAFETY: string will not be dropped while Parser is in scope + char_iter: unsafe { deborrow(&string).chars() }, + string, + file: file.unwrap_or("".to_owned()), + }; + tokenizer.read_tokens() } impl<'a> Tokenizer<'a> { - pub fn tokenize(string: String) -> Result, ParseError> { - let mut parser = Tokenizer { - // SAFETY: string will not be dropped while Parser is in scope - char_iter: unsafe { deborrow(&string).chars() }, - string, - }; - parser.read_tokens() - } - fn tpos(&self, tokens: &[Token]) -> CodePos { CodePos { file: None, @@ -37,13 +39,14 @@ impl<'a> Tokenizer<'a> { } } - fn read_tokens(&mut self) -> Result, ParseError> { + fn read_tokens(mut self) -> Result, ParseError> { let mut ret = Vec::new(); + ret.push(Token::Filename(self.file.clone())); let mut accum = String::new(); let mut in_string = false; let mut in_escape = false; - let mut line = 0; + let mut line = 1; while let Some(char) = self.char_iter.next() { if in_string { if in_escape { diff --git a/src/word.rs b/src/word.rs index 4ebcc4f..d89d26d 100644 --- a/src/word.rs +++ b/src/word.rs @@ -25,7 +25,14 @@ pub enum Word { StartWhile, Confirm(bool), Block(Vec), - Function(String, Vec, Vec, Vec), + Function { + name: String, + args: Vec, + rets: Vec, + code: Vec, + file: String, + line: usize, + }, Return, } diff --git a/std.aea b/std.aea index 5361b49..f3d6099 100644 --- a/std.aea +++ b/std.aea @@ -9,7 +9,7 @@ print("Hi 2"); "hi":print; fn test(a) ret { - ret= print(a) ! + ret= print(a!)! } "hiiii" print;