Skip to content

Commit

Permalink
Merge pull request #17 from ricglz/fourth_delivery
Browse files Browse the repository at this point in the history
Fourth delivery
  • Loading branch information
ricglz authored May 9, 2022
2 parents b6db3bd + e2fc395 commit 9e6abca
Show file tree
Hide file tree
Showing 16 changed files with 685 additions and 331 deletions.
5 changes: 5 additions & 0 deletions examples/invalid/undeclared-variable-if.ra
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
func main(): void {
if (a < 2) {
print(2);
}
}
6 changes: 6 additions & 0 deletions examples/invalid/undeclared-variable-while.ra
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
func main(): void {
while (a < 2) {
print(2);
}
}

18 changes: 18 additions & 0 deletions examples/valid/condition.ra
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
func main(): void {
if (1 < 2) {
a = 1;
} else if (2 < 3) {
a = 2;
} else {
a = 3;
}
if (1 > 2) {
b = 1;
} else {
b = 2;
}
if (1 == 1) {
c = 1;
}
print(a, b, c);
}
8 changes: 8 additions & 0 deletions examples/valid/for.ra
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
func main(): void {
b = 5;
for (a = 1 to b + 1) {
c = a;
print(c);
}
print(a, b);
}
7 changes: 7 additions & 0 deletions examples/valid/while.ra
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
func main(): void {
a = 1;
while (a < 10) {
a = a + 1;
}
print(a);
}
38 changes: 38 additions & 0 deletions src/ast/ast_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,23 @@ pub enum AstNodeKind<'a> {
exprs: Vec<AstNode<'a>>,
},
Read,
Decision {
expr: Box<AstNode<'a>>,
statements: Vec<AstNode<'a>>,
else_block: Option<Box<AstNode<'a>>>,
},
ElseBlock {
statements: Vec<AstNode<'a>>,
},
While {
expr: Box<AstNode<'a>>,
statements: Vec<AstNode<'a>>,
},
For {
assignment: Box<AstNode<'a>>,
expr: Box<AstNode<'a>>,
statements: Vec<AstNode<'a>>,
},
}

impl<'a> From<AstNodeKind<'a>> for String {
Expand All @@ -49,6 +66,7 @@ impl<'a> From<AstNodeKind<'a>> for String {
AstNodeKind::Integer(n) => n.to_string(),
AstNodeKind::Id(s) => s.to_string(),
AstNodeKind::String(s) => s.to_string(),
AstNodeKind::Assignment { name, .. } => name,
node => unreachable!("Node {:?}, cannot be a string", node),
}
}
Expand Down Expand Up @@ -96,6 +114,26 @@ impl fmt::Debug for AstNodeKind<'_> {
AstNodeKind::BinaryOperation { operator, lhs, rhs } => {
write!(f, "BinaryOperation({:?}, {:?}, {:?})", operator, lhs, rhs)
}
AstNodeKind::Decision {
expr,
statements,
else_block,
} => {
write!(f, "Decision({expr:?}, {statements:?}, {else_block:?})")
}
AstNodeKind::ElseBlock { statements } => {
write!(f, "ElseBlock({:?})", statements)
}
AstNodeKind::While { expr, statements } => {
write!(f, "While({:?}, {:?})", expr, statements)
}
AstNodeKind::For {
expr,
statements,
assignment,
} => {
write!(f, "For({expr:?}, {statements:?}, {assignment:?})")
}
}
}
}
29 changes: 29 additions & 0 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,35 @@ impl<'a> From<AstNode<'a>> for String {
}
}

impl<'a> AstNode<'a> {
pub fn expand_node(v: AstNode<'a>) -> Vec<AstNode<'a>> {
let node = v.clone();
match &v.kind {
AstNodeKind::Decision { statements, .. }
| AstNodeKind::ElseBlock { statements }
| AstNodeKind::While { statements, .. } => statements
.to_owned()
.into_iter()
.flat_map(AstNode::expand_node)
.collect(),
AstNodeKind::For {
statements,
assignment,
..
} => vec![*assignment.clone()]
.to_owned()
.into_iter()
.chain(statements.to_owned())
.flat_map(AstNode::expand_node)
.collect(),
_ => vec![node],
}
}
pub fn new(kind: AstNodeKind<'a>, span: Span<'a>) -> AstNode<'a> {
AstNode { kind, span }
}
}

impl fmt::Debug for AstNode<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self.kind)
Expand Down
6 changes: 5 additions & 1 deletion src/dir_func/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ impl Function {
) -> Results<'a, Self> {
let errors: Vec<RaoulError> = nodes
.into_iter()
.filter_map(|node| self.insert_variable_from_node(node, global_fn).err())
.flat_map(AstNode::expand_node)
.filter_map(|node| {
self.insert_variable_from_node(node.to_owned(), global_fn)
.err()
})
.collect();
if errors.is_empty() {
Ok(self.to_owned())
Expand Down
30 changes: 29 additions & 1 deletion src/enums/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::fmt;

use crate::ast::ast_kind::AstNodeKind;
use crate::ast::AstNode;
use crate::dir_func::function::VariablesTable;
Expand All @@ -14,7 +16,7 @@ pub enum Types {
}

impl Types {
fn is_boolish(&self) -> bool {
pub fn is_boolish(&self) -> bool {
match self {
Types::INT | Types::BOOL => true,
_ => false,
Expand All @@ -28,6 +30,14 @@ impl Types {
}
}

pub fn can_cast(&self, to: Types) -> bool {
match to {
Types::BOOL => self.is_boolish(),
Types::FLOAT => self.is_number(),
_ => to == self.to_owned(),
}
}

pub fn binary_operator_type(
operator: Operator,
lhs_type: Types,
Expand Down Expand Up @@ -160,9 +170,27 @@ pub enum Operator {
Minus,
Times,
Div,
Inc,
// ByteCode
Assignment,
Print,
PrintNl,
Read,
Goto,
GotoF,
}

impl Operator {
pub fn is_goto(&self) -> bool {
match self {
Operator::Goto | Operator::GotoF => true,
_ => false,
}
}
}

impl fmt::Display for Operator {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:10}", format!("{:?}", self))
}
}
39 changes: 20 additions & 19 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ mod error;
mod parser;
mod quadruple;

use ast::AstNode;
use dir_func::DirFunc;
use error::Results;
use parser::parse;
use quadruple::QuadrupleManager;
use quadruple::quadruple_manager::QuadrupleManager;

// ANCHOR: Testing the examples
mod test_parser;
Expand All @@ -22,6 +24,22 @@ use std::process::exit;

use args::parse_args;

fn parse_ast<'a>(ast: AstNode<'a>, debug: bool) -> Results<'a, ()> {
let mut dir_func = DirFunc::new();
dir_func.build_dir_func(ast.clone())?;
if debug {
println!("Dir func created sucessfully");
println!("{:#?}", dir_func);
}
let mut quad_manager = QuadrupleManager::new(&mut dir_func);
quad_manager.parse(ast.clone())?;
Ok(if debug {
println!("Quads created sucessfully");
println!("{:#?}", quad_manager.memory);
println!("{:?}", quad_manager);
})
}

fn main() {
let matches = parse_args();
let filename = matches.value_of("file").expect("required");
Expand All @@ -40,29 +58,12 @@ fn main() {
println!("Parsing ended sucessfully");
println!("AST:\n{:?}", ast);
}
let mut dir_func = DirFunc::new();
if let Err(errors) = dir_func.build_dir_func(ast.clone()) {
if let Err(errors) = parse_ast(ast, debug) {
for error in errors {
println!("{:?}", error);
}
exit(1);
}
if debug {
println!("Dir func created sucessfully");
println!("{:#?}", dir_func);
}
let mut quad_manager = QuadrupleManager::new(&mut dir_func);
if let Err(errors) = quad_manager.parse(ast.clone()) {
for error in errors {
println!("{:?}", error);
}
exit(1);
}
if debug {
println!("Quads created sucessfully");
println!("{:#?}", quad_manager.memory);
println!("{:#?}", quad_manager.quad_list);
}
}

#[cfg(test)]
Expand Down
14 changes: 7 additions & 7 deletions src/parser/grammar.pest
Original file line number Diff line number Diff line change
Expand Up @@ -151,16 +151,16 @@ function = { FUNC_HEADER ~ block }
MAIN_FUNCTION = _{ FUNC ~ MAIN ~ L_PAREN ~ R_PAREN ~ COLON ~ void ~ block }
FUNC_CALL = { id ~ L_PAREN ~ exprs? ~ R_PAREN }

COND_EXPR = { L_PAREN ~ expr ~ R_PAREN }
IF_BLOCK = { IF ~ COND_EXPR ~ block }
ELSE_BLOCK = { ELSE ~ (block | DECISION) }
DECISION = { IF_BLOCK ~ ELSE_BLOCK? }
COND_EXPR = _{ L_PAREN ~ expr ~ R_PAREN }
if_block = _{ IF ~ COND_EXPR ~ block }
else_block = { ELSE ~ (block | decision) }
decision = { if_block ~ else_block? }

write = {PRINT ~ L_PAREN ~ exprs? ~ R_PAREN }

WHILE_LOOP = {WHILE ~ COND_EXPR ~ block}
while_loop = {WHILE ~ COND_EXPR ~ block}

FOR_LOOP = {FOR ~ L_PAREN ~ assignment ~ TO ~ expr ~ R_PAREN ~ block}
for_loop = {FOR ~ L_PAREN ~ assignment ~ TO ~ expr ~ R_PAREN ~ block}

POSSIBLE_STR = {STRING_CTE | NON_CTE}
READ_CSV_EXTRA = {(COMMA ~ id){2}}
Expand All @@ -179,7 +179,7 @@ DATAFRAME_VOID_OPS = _{PLOT | HISTOGRAM}

RETURN = { RETURN_KEY ~ expr }

BLOCK_STATEMENT = _{ DECISION | WHILE_LOOP | FOR_LOOP }
BLOCK_STATEMENT = _{ decision | while_loop | for_loop }
INLINE_STATEMENT = _{ DATAFRAME_VOID_OPS | assignment | write | RETURN | FUNC_CALL }
statement = { INLINE_STATEMENT ~ SEMI_COLON | BLOCK_STATEMENT }

Expand Down
Loading

0 comments on commit 9e6abca

Please sign in to comment.