-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: lexing and parsing let keyword for defining variables
- Loading branch information
Mateusz Russak
committed
Dec 10, 2023
1 parent
575e607
commit d58bdea
Showing
20 changed files
with
1,520 additions
and
981 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
use std::{fmt::{Display, Formatter}}; | ||
|
||
use lexer::PError; | ||
use parser::{Node, Op, Value}; | ||
use vm::{Instr, Instrs, OpCode}; | ||
struct Code { | ||
code: Vec<VInst>, | ||
} | ||
|
||
impl Code { | ||
pub fn new() -> Code { | ||
Code { | ||
code: Vec::new(), | ||
} | ||
} | ||
pub fn push(&mut self, inst: VInst) -> usize { | ||
self.code.push(inst); | ||
self.code.len() - 1 | ||
} | ||
pub fn append(&mut self, code: Code) { | ||
self.code.extend(code.code); | ||
} | ||
pub fn to_bytes(&self) -> Vec<u8> { | ||
vec![] | ||
} | ||
|
||
pub fn size(&self) -> usize { | ||
self.code.iter().map(|c| c.op_code.size()).sum() | ||
} | ||
} | ||
|
||
enum VArg { | ||
Reg(u8), | ||
Rel(i32), | ||
Abs(u32), | ||
} | ||
|
||
enum VState { | ||
Incomplete, | ||
Complete, | ||
} | ||
|
||
struct VInst { | ||
state: VState, | ||
label: String, | ||
op_code: OpCode, | ||
args: Vec<VArg>, | ||
inst: Option<Instr> | ||
} | ||
|
||
impl VInst { | ||
pub fn new(op_code: OpCode, args: Vec<VArg>) -> VInst { | ||
VInst { | ||
state: VState::Incomplete, | ||
label: String::new(), | ||
op_code, | ||
args, | ||
inst: None, | ||
} | ||
} | ||
pub fn build(&mut self) { | ||
self.inst = Some( | ||
match self.op_code { | ||
OpCode::Load => Instr::Load(self.args[0], self.args[1]), | ||
_ => panic!("Unknown op code: {}", self.op_code) | ||
} | ||
); | ||
self.state = VState::Complete; | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod compiler_code_tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn test_code() { | ||
let mut code = Code::new(); | ||
code.push(VInst::new(OpCode::Load, vec![VArg::Reg(0), VArg::Abs(0)])); | ||
assert!(code.size() == 4); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
use std::slice::Iter; | ||
use lexer::{Token, PError}; | ||
use super::{Op, Expression, Node, Params}; | ||
use lexer::Location; | ||
use crate::Parser; | ||
use crate::{expect, accept}; | ||
|
||
pub struct Define; | ||
|
||
impl Parser for Define { | ||
fn consume(token: &Token, iter: &mut Iter<Token>) -> Result<(Node, Option<Token>), PError> { | ||
let name = accept!(iter, Id); | ||
let Token::Id(_loc, id) = name else { | ||
panic!("Unexpected token"); | ||
}; | ||
|
||
let mut tree = Node::new(Op::DefineVar, token.get_location()).set_id(id.clone()); | ||
|
||
let Some(tok) = iter.next() else { | ||
return Err(PError::new(Location::Eof, "Unexpected end of file")); | ||
}; | ||
|
||
match tok { | ||
Token::Assign(loc) => { | ||
let mut assign = Node::new(Op::Assign, name.get_location()); | ||
assign.add(Node::new(Op::Variable, name.get_location()).set_id(id.to_string())); | ||
let (exp, tok) = Expression::consume(token, iter)?; | ||
expect!(tok.clone(), Semi); | ||
assign.add(exp); | ||
tree.add(assign); | ||
Ok((tree, tok)) | ||
}, | ||
Token::Semi(loc) => { | ||
Ok((tree, Some(tok.clone()))) | ||
}, | ||
_ => { | ||
Err(PError::new(token.get_location(), "Unexpected token")) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
|
||
#[macro_export] | ||
macro_rules! accept { | ||
( $iter:ident, $token:ident ) => { | ||
{ | ||
let Some(token) = $iter.next() else { | ||
return Err(PError::new(Location::Eof, "Unexpected end of file")); | ||
}; | ||
if !matches!(token, Token::$token(..)) { | ||
return Err(PError::new(token.get_location(), format!("Unexpected token: {}", token).as_str())) | ||
} | ||
token | ||
} | ||
}; | ||
} | ||
#[macro_export] | ||
macro_rules! expect { | ||
( $ret:expr, $token:ident ) => { | ||
let Some(token) = $ret else { | ||
return Err(PError::new(Location::Eof, "Unexpected end of file")) | ||
}; | ||
if !matches!(token, Token::$token(..)) { | ||
return Err(PError::new(token.get_location(),format!("Unexpected token: {}", token).as_str())) | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
mod helpers; | ||
mod node; | ||
mod value; | ||
|
||
pub use helpers::*; | ||
pub use node::*; | ||
pub use value::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.