Skip to content

Commit

Permalink
Add wait and post to parser
Browse files Browse the repository at this point in the history
  • Loading branch information
leonidas1712 committed Apr 18, 2024
1 parent 9d3a01a commit 0760cfb
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 1 deletion.
2 changes: 2 additions & 0 deletions compiler/oxidate/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,8 @@ impl Compiler {
// push RESET
arr.push(ByteCode::RESET(bytecode::FrameType::CallFrame))
}
Decl::WaitStmt(_) => {}
Decl::PostStmt(_) => {}
};

Ok(())
Expand Down
19 changes: 19 additions & 0 deletions src/lexer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ pub enum Token {
#[token("join")]
Join,

#[token("wait")]
Wait,

#[token("post")]
Post,

#[token("false", |_| false)]
#[token("true", |_| true)]
Bool(bool),
Expand Down Expand Up @@ -222,6 +228,8 @@ impl Token {
Self::FnDeclReturn => "->".to_string(),
Self::Spawn => "spawn".to_string(),
Self::Join => "join".to_string(),
Self::Wait => "wait".to_string(),
Self::Post => "post".to_string(),
}
}
}
Expand Down Expand Up @@ -636,4 +644,15 @@ mod test {
assert_eq!(lexer.next().unwrap().unwrap(), Token::Spawn);
assert_eq!(lexer.next().unwrap().unwrap(), Token::Join);
}

#[test]
fn test_lex_wait_post() {
let t = r"
wait post
";
let mut lexer = Token::lexer(t);

assert_eq!(lexer.next().unwrap().unwrap(), Token::Wait);
assert_eq!(lexer.next().unwrap().unwrap(), Token::Post);
}
}
62 changes: 61 additions & 1 deletion src/parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,25 @@ impl<'inp> Parser<'inp> {
Err(ParseError::new("join expected variable for thread to join"))
}
}
// wait sem;
Token::Wait => {
self.advance();
let sem = self.parse_expr(0)?.to_expr()?;
if let Expr::Symbol(sem_sym) = sem {
Ok(Decl::WaitStmt(sem_sym))
} else {
Err(ParseError::new("wait expected semaphore variable"))
}
}
Token::Post => {
self.advance();
let sem = self.parse_expr(0)?.to_expr()?;
if let Expr::Symbol(sem_sym) = sem {
Ok(Decl::PostStmt(sem_sym))
} else {
Err(ParseError::new("post expected semaphore variable"))
}
}
// if not is_loop, error
Token::Break => {
if !self.is_loop {
Expand Down Expand Up @@ -397,7 +416,7 @@ mod tests {
}

#[test]
fn test_parse_spawn_join() {
fn test_parse_concurrency() {
let t = r"
let t = spawn func();
spawn f2();
Expand All @@ -416,5 +435,46 @@ mod tests {
let res = join t;
";
test_parse(t, "let t = spawn func();let res = join t;");

// wait and post
let t = r"
let sem = sem_create();
wait sem;
post sem;
";
test_parse(t, "let sem = sem_create();wait sem;post sem;");

let t = r"
wait 2+2;
";
test_parse_err(t, "expected semaphore variable", true);

let t = r"
post 2+2;
";
test_parse_err(t, "expected semaphore variable", true);

// can't assign wait/post
let t = r"
let x = wait sem;
";
test_parse_err(t, "wait is not an expression", true);

// can't assign wait/post
let t = r"
let x = post sem;
";
test_parse_err(t, "post is not an expression", true);

// must be stmt with semi
let t = r"
wait sem
";
test_parse_err(t, "Expected semicolon", true);

let t = r"
post sem
";
test_parse_err(t, "Expected semicolon", true);
}
}
8 changes: 8 additions & 0 deletions src/parser/src/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,10 @@ pub enum Decl {
BreakStmt,
// only inside fn
ReturnStmt(Option<Expr>),
// wait sem; - stmt only
WaitStmt(String),
// post sem; - stmt only
PostStmt(String),
}

impl Decl {
Expand All @@ -284,6 +288,8 @@ impl Decl {
Self::LoopStmt(_) => Err(ParseError::new("loop is not an expression")),
Self::BreakStmt => Err(ParseError::new("break is not an expression")),
Self::ReturnStmt(_) => Err(ParseError::new("return is not an expression")),
Self::WaitStmt(_) => Err(ParseError::new("wait is not an expression")),
Self::PostStmt(_) => Err(ParseError::new("post is not an expression")),
Self::ExprStmt(expr) => Ok(expr.clone()),
}
}
Expand Down Expand Up @@ -326,6 +332,8 @@ impl Display for Decl {
};
format!("{}{}", Token::Return, str)
}
Decl::WaitStmt(sym) => format!("wait {}", sym),
Decl::PostStmt(sym) => format!("post {}", sym),
};

write!(f, "{}", string)
Expand Down
10 changes: 10 additions & 0 deletions src/types/src/type_checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,16 @@ impl<'prog> TypeChecker<'prog> {
must_break: true,
must_return: true,
}),
Decl::WaitStmt(_) => Ok(CheckResult {
ty: Type::Unit,
must_break: false,
must_return: false,
}),
Decl::PostStmt(_) => Ok(CheckResult {
ty: Type::Unit,
must_break: false,
must_return: false,
}),
}

// Ok(())
Expand Down

0 comments on commit 0760cfb

Please sign in to comment.