fix some bugs, add StartIf and StartWhile

This commit is contained in:
TudbuT 2024-01-15 17:16:53 +01:00
parent 0b1ded01a6
commit 72ae4d8ef2
4 changed files with 48 additions and 17 deletions

View file

@ -22,7 +22,7 @@ fn main() {
println!("Starting call to {n} with objcall = {o}");
call_stack.push((n, o))
}
Word::ConfirmCall(p) => {
Word::Confirm(p) => {
let dat = call_stack.pop().unwrap();
println!(
"Confirmed call to {} with return popping = {p} and objcall = {}",

View file

@ -18,10 +18,17 @@ pub enum ParseError {
InvalidToken(CodePos, String),
StringInIdent(CodePos),
UnexpectedEOF,
UnexpectedOpenParen(CodePos),
UnexpectedParen(CodePos),
FunctionCallWithoutFn(CodePos),
UnexpectedToken(CodePos, Token, String),
ExpectedIdentifierAfterColon(CodePos),
ExpectedParen(CodePos),
}
#[derive(Default)]
struct State {
is_objcall: bool,
paren_mode: Vec<bool>,
}
pub struct Parser<'a> {
@ -89,7 +96,8 @@ impl<'a> Parser<'a> {
self.slice[0..self.index]
.iter()
.filter(|t| matches!(t, Token::Newline(_)))
.count(),
.count()
+ 1,
),
}
}
@ -99,11 +107,6 @@ impl<'a> Parser<'a> {
let mut words = Vec::new();
let mut file = None;
#[derive(Default)]
struct State {
is_objcall: bool,
paren_mode: Vec<bool>,
}
let mut state = State {
..Default::default()
};
@ -111,11 +114,29 @@ impl<'a> Parser<'a> {
while let Ok(token) = self.next() {
match token {
Token::Space => (),
Token::Exclam => words.push(Word::ConfirmCall(false)),
Token::Semicolon => words.push(Word::ConfirmCall(true)),
Token::Exclam => {
if state.paren_mode.pop().ok_or(ParseError::UnexpectedToken(
self.pos(),
Token::Semicolon,
String::new(),
))? {
Err(ParseError::ExpectedParen(self.pos()))?;
}
words.push(Word::Confirm(false))
}
Token::Semicolon => {
if state.paren_mode.pop().ok_or(ParseError::UnexpectedToken(
self.pos(),
Token::Semicolon,
String::new(),
))? {
Err(ParseError::ExpectedParen(self.pos()))?;
}
words.push(Word::Confirm(true))
}
Token::Colon => {
if words.last().is_some_and(|x| !matches!(x, Word::Const(_))) {
words.push(Word::ConfirmCall(false));
words.push(Word::Confirm(false));
}
state.is_objcall = true;
}
@ -123,13 +144,18 @@ impl<'a> Parser<'a> {
state
.paren_mode
.pop()
.ok_or(ParseError::UnexpectedOpenParen(self.pos()))?;
.ok_or(ParseError::UnexpectedParen(self.pos()))?;
state.paren_mode.push(true);
}
Token::Close => {
words.push(Word::ConfirmCall(
self.next_matches(|x| *x == Token::Semicolon),
));
if !state
.paren_mode
.pop()
.ok_or(ParseError::UnexpectedParen(self.pos()))?
{
Err(ParseError::UnexpectedParen(self.pos()))?;
}
words.push(Word::Confirm(self.next_matches(|x| *x == Token::Semicolon)));
}
Token::Begin => {
words.push(Word::Block(self.read_level_at(self.index + 1)?));
@ -201,6 +227,8 @@ impl<'a> Parser<'a> {
self.read_level_at(self.index)?,
)))
}
"if" => Ok(Some(Word::StartIf)),
"while" => Ok(Some(Word::StartWhile)),
_ => Ok(None),
}
}

View file

@ -21,7 +21,9 @@ pub enum Argdef {
pub enum Word {
Const(Value),
StartCall(String, bool),
ConfirmCall(bool),
StartIf,
StartWhile,
Confirm(bool),
Block(Vec<Word>),
Function(String, Vec<Argdef>, Vec<Argdef>, Vec<Word>),
Return,

View file

@ -1,6 +1,7 @@
print "Hi 1" ;
"Hi 1" print;
"Hi 1" print()
"hi 2" print ;
print("Hi 2");