properly implement code tracing
This commit is contained in:
parent
72ae4d8ef2
commit
d36381bb4e
7 changed files with 58 additions and 41 deletions
5
src/lib.rs
Normal file
5
src/lib.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
pub mod parser;
|
||||||
|
pub mod tokenizer;
|
||||||
|
pub mod ty;
|
||||||
|
pub mod value;
|
||||||
|
pub mod word;
|
25
src/main.rs
25
src/main.rs
|
@ -1,15 +1,13 @@
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
use crate::{parser::Parser, tokenizer::Tokenizer, value::Value, word::Word};
|
use aeapa::{parser::Parser, tokenizer::tokenize, value::Value, word::Word};
|
||||||
|
|
||||||
pub mod parser;
|
|
||||||
pub mod tokenizer;
|
|
||||||
pub mod ty;
|
|
||||||
pub mod value;
|
|
||||||
pub mod word;
|
|
||||||
|
|
||||||
fn main() {
|
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:?}");
|
println!("{tokens:?}");
|
||||||
let words = Parser::parse(&tokens).unwrap();
|
let words = Parser::parse(&tokens).unwrap();
|
||||||
println!("{words:?}");
|
println!("{words:?}");
|
||||||
|
@ -32,8 +30,15 @@ fn main() {
|
||||||
println!("{}", stack.pop().unwrap());
|
println!("{}", stack.pop().unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Word::Function(name, args, ret, words) => {
|
Word::Function {
|
||||||
println!("If i was an interpreter I would define function {name}({args:?}) {ret:?} {{{words:?}}}")
|
name,
|
||||||
|
args,
|
||||||
|
rets,
|
||||||
|
code,
|
||||||
|
file,
|
||||||
|
line,
|
||||||
|
} => {
|
||||||
|
println!("If i was an interpreter I would define function {name}({args:?}) {rets:?} {{{code:?}}} of {file}:{line}")
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ pub enum ParseError {
|
||||||
UnexpectedToken(CodePos, Token, String),
|
UnexpectedToken(CodePos, Token, String),
|
||||||
ExpectedIdentifierAfterColon(CodePos),
|
ExpectedIdentifierAfterColon(CodePos),
|
||||||
ExpectedParen(CodePos),
|
ExpectedParen(CodePos),
|
||||||
|
NeedFileToken,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -34,6 +35,7 @@ struct State {
|
||||||
pub struct Parser<'a> {
|
pub struct Parser<'a> {
|
||||||
slice: &'a [Token],
|
slice: &'a [Token],
|
||||||
index: usize,
|
index: usize,
|
||||||
|
line: usize,
|
||||||
file: Option<String>,
|
file: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +44,7 @@ impl<'a> Parser<'a> {
|
||||||
Parser {
|
Parser {
|
||||||
slice: tokens,
|
slice: tokens,
|
||||||
index: 0,
|
index: 0,
|
||||||
|
line: 0,
|
||||||
file: None,
|
file: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,20 +95,13 @@ impl<'a> Parser<'a> {
|
||||||
file: self.file.as_ref().cloned(),
|
file: self.file.as_ref().cloned(),
|
||||||
char_in_file: None,
|
char_in_file: None,
|
||||||
token: Some(self.index),
|
token: Some(self.index),
|
||||||
line: Some(
|
line: Some(self.line),
|
||||||
self.slice[0..self.index]
|
|
||||||
.iter()
|
|
||||||
.filter(|t| matches!(t, Token::Newline(_)))
|
|
||||||
.count()
|
|
||||||
+ 1,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_level_at(&mut self, index: usize) -> Result<Vec<Word>, ParseError> {
|
pub fn read_level_at(&mut self, index: usize) -> Result<Vec<Word>, ParseError> {
|
||||||
self.index = index;
|
self.index = index;
|
||||||
let mut words = Vec::new();
|
let mut words = Vec::new();
|
||||||
let mut file = None;
|
|
||||||
|
|
||||||
let mut state = State {
|
let mut state = State {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -172,11 +168,8 @@ impl<'a> Parser<'a> {
|
||||||
state.paren_mode.push(false);
|
state.paren_mode.push(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token::Newline(_) => (),
|
Token::Newline(n) => self.line = n,
|
||||||
Token::Filename(f) => file = Some(f),
|
Token::Filename(f) => self.file = Some(f),
|
||||||
}
|
|
||||||
if self.file != file {
|
|
||||||
self.file = file.clone();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(words)
|
Ok(words)
|
||||||
|
@ -185,6 +178,7 @@ impl<'a> Parser<'a> {
|
||||||
fn try_match_keyword(&mut self, ident: &String) -> Result<Option<Word>, ParseError> {
|
fn try_match_keyword(&mut self, ident: &String) -> Result<Option<Word>, ParseError> {
|
||||||
match ident.as_str() {
|
match ident.as_str() {
|
||||||
"fn" => {
|
"fn" => {
|
||||||
|
let line = self.line;
|
||||||
let name = self.next_as_ident()?;
|
let name = self.next_as_ident()?;
|
||||||
self.assert_next_eq(Token::Open)?;
|
self.assert_next_eq(Token::Open)?;
|
||||||
let mut arr = Vec::new();
|
let mut arr = Vec::new();
|
||||||
|
@ -220,12 +214,14 @@ impl<'a> Parser<'a> {
|
||||||
))?,
|
))?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Some(Word::Function(
|
Ok(Some(Word::Function {
|
||||||
name,
|
name,
|
||||||
args,
|
args,
|
||||||
arr,
|
rets: arr,
|
||||||
self.read_level_at(self.index)?,
|
code: self.read_level_at(self.index)?,
|
||||||
)))
|
file: self.file.as_ref().ok_or(ParseError::NeedFileToken)?.clone(),
|
||||||
|
line,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
"if" => Ok(Some(Word::StartIf)),
|
"if" => Ok(Some(Word::StartIf)),
|
||||||
"while" => Ok(Some(Word::StartWhile)),
|
"while" => Ok(Some(Word::StartWhile)),
|
||||||
|
|
1
src/runtime.rs
Normal file
1
src/runtime.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub struct Runtime {}
|
|
@ -7,21 +7,23 @@ use crate::{
|
||||||
word::Token,
|
word::Token,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Tokenizer<'a> {
|
struct Tokenizer<'a> {
|
||||||
char_iter: Chars<'a>,
|
char_iter: Chars<'a>,
|
||||||
string: String,
|
string: String,
|
||||||
|
file: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tokenize(string: String, file: Option<String>) -> Result<Vec<Token>, 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("<dynamic>".to_owned()),
|
||||||
|
};
|
||||||
|
tokenizer.read_tokens()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Tokenizer<'a> {
|
impl<'a> Tokenizer<'a> {
|
||||||
pub fn tokenize(string: String) -> Result<Vec<Token>, 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 {
|
fn tpos(&self, tokens: &[Token]) -> CodePos {
|
||||||
CodePos {
|
CodePos {
|
||||||
file: None,
|
file: None,
|
||||||
|
@ -37,13 +39,14 @@ impl<'a> Tokenizer<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_tokens(&mut self) -> Result<Vec<Token>, ParseError> {
|
fn read_tokens(mut self) -> Result<Vec<Token>, ParseError> {
|
||||||
let mut ret = Vec::new();
|
let mut ret = Vec::new();
|
||||||
|
ret.push(Token::Filename(self.file.clone()));
|
||||||
|
|
||||||
let mut accum = String::new();
|
let mut accum = String::new();
|
||||||
let mut in_string = false;
|
let mut in_string = false;
|
||||||
let mut in_escape = false;
|
let mut in_escape = false;
|
||||||
let mut line = 0;
|
let mut line = 1;
|
||||||
while let Some(char) = self.char_iter.next() {
|
while let Some(char) = self.char_iter.next() {
|
||||||
if in_string {
|
if in_string {
|
||||||
if in_escape {
|
if in_escape {
|
||||||
|
|
|
@ -25,7 +25,14 @@ pub enum Word {
|
||||||
StartWhile,
|
StartWhile,
|
||||||
Confirm(bool),
|
Confirm(bool),
|
||||||
Block(Vec<Word>),
|
Block(Vec<Word>),
|
||||||
Function(String, Vec<Argdef>, Vec<Argdef>, Vec<Word>),
|
Function {
|
||||||
|
name: String,
|
||||||
|
args: Vec<Argdef>,
|
||||||
|
rets: Vec<Argdef>,
|
||||||
|
code: Vec<Word>,
|
||||||
|
file: String,
|
||||||
|
line: usize,
|
||||||
|
},
|
||||||
Return,
|
Return,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
std.aea
2
std.aea
|
@ -9,7 +9,7 @@ print("Hi 2");
|
||||||
"hi":print;
|
"hi":print;
|
||||||
|
|
||||||
fn test(a) ret {
|
fn test(a) ret {
|
||||||
ret= print(a) !
|
ret= print(a!)!
|
||||||
}
|
}
|
||||||
|
|
||||||
"hiiii" print;
|
"hiiii" print;
|
||||||
|
|
Loading…
Add table
Reference in a new issue