Skip to content

Commit

Permalink
Merge pull request #2 from ricglz/proposal_feedback
Browse files Browse the repository at this point in the history
proposal feedback
  • Loading branch information
ricglz authored Apr 8, 2022
2 parents 106bcc6 + 5bfe266 commit ae04be9
Show file tree
Hide file tree
Showing 14 changed files with 166 additions and 79 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Raoul

Imperative language done as compilers class final project

## How to run it?

```
cargo run -- examples/filename.ra
```

### Flags

- `-d` or `--debug`. Shows debugging message for the developer of the language
26 changes: 19 additions & 7 deletions examples/complete.ra
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,28 @@ func helper(a: int): int {

func main(): void {
global globalVariable = 2;
global globalArray = [3, 2, 1];

a = 1;
b = "abc";
c = 2.0;
d = true;
e = [1, 2, 3];
arr = [1, 2, 3];
matrix = [[1, 2, 3], [1, 2, 3], [1, 2, 3]];
f = helper(a);
g = input();

print(e[0]);
print(arr[0]);
arr[0] = 3;
print(arr[0]);

print(matrix[0][a - 1]);
matrix[0][a - 1] = 3;
print(matrix[0][a - 1]);

print(globalArray[0]);
global globalArray[0] = 1;
print(globalArray[0]);

if (a < c) {
print(a);
Expand All @@ -34,13 +46,13 @@ func main(): void {

dataframe = read_csv('file.csv', rows, cols);

print(average(dataframe));
print(std(dataframe));
print(mode(dataframe));
print(variance(dataframe));

print(average(dataframe, 'column'));
print(std(dataframe, 'column'));
print(mode(dataframe, 'column'));
print(variance(dataframe, 'column'));

print(correlation(dataframe, 'column1', 'column2'));

plot(dataframe, 'column1', 'column2');
histogram(dataframe, 'column1', 10);
}
Binary file modified propuesta/images/Raoul-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified propuesta/images/Raoul-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified propuesta/images/Raoul-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified propuesta/images/Raoul-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified propuesta/images/Raoul-5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified propuesta/images/Raoul-6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed propuesta/images/Raoul-7.png
Binary file not shown.
30 changes: 17 additions & 13 deletions src/args/mod.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
use clap::{Arg, Command, ArgMatches};
use clap::{Arg, ArgMatches, Command};

pub fn parse_args() -> ArgMatches {
Command::new("raoul")
.version("1.0")
.author("ricglz")
.about("My cool programming language")
.arg(Arg::new("file")
.value_name("FILE")
.help("Sets a file to parse")
.required(true))
.arg(Arg::new("verbose")
.short('v')
.long("verbose")
.value_name("VERBOSE")
.help("Makes it verbose")
.default_value("false")
.takes_value(false)
.required(false))
.arg(
Arg::new("file")
.value_name("FILE")
.help("Sets a file to parse")
.required(true),
)
.arg(
Arg::new("verbose")
.short('d')
.long("debug")
.value_name("DEBUG")
.help("Displays debugging prints throughout the process")
.default_value("false")
.takes_value(false)
.required(false),
)
.get_matches()
}
16 changes: 9 additions & 7 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
mod args;
mod enums;
mod parser;
mod test_parser;
#[macro_use]
extern crate pest_derive;

use std::process::exit;

use crate::parser::parse;
use crate::args::parse_args;
use args::parse_args;
use test_parser::parse_file;

fn main() {
let matches = parse_args();
let filename = matches.value_of("file").expect("required");
let verbose = matches.is_present("verbose");
if verbose {
let debug = matches.is_present("debug");
if debug {
println!("Starting parsing");
}
if let Err(error) = parse(filename, verbose) {
if let Err(error) = parse_file(filename, debug) {
println!("Parsing error {}", error.to_string());
exit(1);
}
if verbose {
if debug {
println!("Parsing ended sucessfully");
}
}
109 changes: 61 additions & 48 deletions src/parser/grammar.pest
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ AND = {"AND"}
OR = {"OR"}
not = {"not"}

BOOL = {"bool"}
FLOAT = {"float"}
INT = {"int"}
STRING = {"string"}
void = {"void"}
BOOL = {"bool"}
FLOAT = {"float"}
INT = {"int"}
STRING = {"string"}
DATAFRAME = {"Dataframe"}
void = {"void"}

FUNC = _{"func"}
MAIN = _{"main"}
Expand All @@ -57,6 +58,9 @@ AVERAGE_KEY = _{"average"}
STD_KEY = _{"std"}
MODE_KEY = _{"mode"}
VARIANCE_KEY = _{"variance"}
CORRELATION_KEY = {"correlation"}
PLOT_KEY = {"plot"}
HISTOGRAM_KEY = {"histogram"}

RETURN_KEY = _{"return"}

Expand All @@ -69,31 +73,34 @@ COMP_OP = _{ EQ | NE }
REL_OP = _{ GT | GTE | LT | LTE }

KEYWORD_TYPE = _{
AND |
OR |
not |
BOOL |
FLOAT |
INT |
STRING |
void |
FUNC |
MAIN |
IF |
ELSE |
PRINT |
WHILE |
FOR |
TO |
GLOBAL |
INPUT |
TRUE |
FALSE |
READ_CSV_KEY |
AVERAGE_KEY |
STD_KEY |
MODE_KEY |
VARIANCE_KEY |
AND |
OR |
not |
BOOL |
FLOAT |
INT |
STRING |
void |
FUNC |
MAIN |
IF |
ELSE |
PRINT |
WHILE |
FOR |
TO |
GLOBAL |
INPUT |
TRUE |
FALSE |
READ_CSV_KEY |
AVERAGE_KEY |
STD_KEY |
MODE_KEY |
VARIANCE_KEY |
CORRELATION_KEY |
PLOT_KEY |
HISTOGRAM_KEY |
RETURN_KEY
}
KEYWORD = _{ KEYWORD_TYPE ~ !ID_SUFFIX }
Expand All @@ -111,7 +118,7 @@ ARR_CTE = { L_SQUARE ~ exprs? ~ R_SQUARE }
CTE = _{ ARR_CTE | ATOM_CTE }
ARR_INDEX = { L_SQUARE ~ expr ~ R_SQUARE }
ARR_VAL = { id ~ ARR_INDEX{1,2} }
NON_CTE = _{ DATAFRAME_OPS | FUNC_CALL | ARR_VAL | id }
NON_CTE = _{ DATAFRAME_VALUE_OPS | FUNC_CALL | ARR_VAL | id }
VAR_VAL = _{ CTE | NON_CTE }

expr = { and_term ~ (OR ~ and_term)* }
Expand All @@ -124,19 +131,20 @@ operand = { not? ~ operand_value }
operand_value = { L_PAREN ~ expr ~ R_PAREN | VAR_VAL }
exprs = { expr ~ (COMMA ~ expr)* }

ATOMIC_TYPES = _{ BOOL | FLOAT | INT | STRING }
ARR_TYPES = { L_SQUARE ~ (ATOMIC_TYPES | ARR_TYPES) ~ R_SQUARE }
VAR_TYPES = _{ ARR_TYPES | ATOMIC_TYPES }
TYPES = _{ VAR_TYPES | void}
ATOMIC_TYPES = _{ BOOL | FLOAT | INT | STRING }
ARR_TYPES = { L_SQUARE ~ (ATOMIC_TYPES | ARR_TYPES) ~ R_SQUARE }
SIMPLE_TYPES = _{ ARR_TYPES | ATOMIC_TYPES }
COMPOSED_TYPES = _{ SIMPLE_TYPES | DATAFRAME }
TYPES = _{ SIMPLE_TYPES | void}

READ = { INPUT ~ L_PAREN ~ R_PAREN }

ASSIGNMENT_EXP = _{ READ | expr }
assignment = { GLOBAL? ~ id ~ ASGN ~ ASSIGNMENT_EXP }
ASSIGNMENT_EXP = _{ READ | READ_CSV | expr }
assignment = { GLOBAL? ~ (ARR_VAL | id) ~ ASGN ~ ASSIGNMENT_EXP }

block = { L_BRACKET ~ statement* ~ R_BRACKET }

FUNC_ARG = { id ~ COLON ~ VAR_TYPES }
FUNC_ARG = { id ~ COLON ~ SIMPLE_TYPES }
FUNC_ARGS = { FUNC_ARG ~ (COMMA ~ FUNC_ARG)* }
FUNC_HEADER = { FUNC ~ id ~ L_PAREN ~ FUNC_ARGS? ~ R_PAREN ~ COLON ~ TYPES }
function = { FUNC_HEADER ~ block }
Expand All @@ -154,20 +162,25 @@ WHILE_LOOP = {WHILE ~ COND_EXPR ~ block}

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

POSSIBLE_STR = {STRING_CTE | NON_CTE}
READ_CSV_EXTRA = {(COMMA ~ id){2}}
READ_CSV = {READ_CSV_KEY ~ L_PAREN ~ POSSIBLE_STR ~ READ_CSV_EXTRA? ~ R_PAREN}
OPTIONAL_COLUMN_FUNC = {L_PAREN ~ id ~ (COMMA ~ POSSIBLE_STR)? ~ R_PAREN}
AVERAGE = {AVERAGE_KEY ~ OPTIONAL_COLUMN_FUNC}
STD = {STD_KEY ~ OPTIONAL_COLUMN_FUNC}
MODE = {MODE_KEY ~ OPTIONAL_COLUMN_FUNC}
VARIANCE = {VARIANCE_KEY ~ OPTIONAL_COLUMN_FUNC}
DATAFRAME_OPS = _{READ_CSV | AVERAGE | STD | MODE | VARIANCE}
POSSIBLE_STR = {STRING_CTE | NON_CTE}
READ_CSV_EXTRA = {(COMMA ~ id){2}}
READ_CSV = {READ_CSV_KEY ~ L_PAREN ~ POSSIBLE_STR ~ READ_CSV_EXTRA? ~ R_PAREN}
ONE_COLUMN_FUNC = {L_PAREN ~ id ~ COMMA ~ POSSIBLE_STR ~ R_PAREN}
AVERAGE = {AVERAGE_KEY ~ ONE_COLUMN_FUNC}
STD = {STD_KEY ~ ONE_COLUMN_FUNC}
MODE = {MODE_KEY ~ ONE_COLUMN_FUNC}
VARIANCE = {VARIANCE_KEY ~ ONE_COLUMN_FUNC}
TWO_COLUMNS_FUNC = {L_PAREN ~ id ~ (COMMA ~ POSSIBLE_STR){2} ~ R_PAREN}
CORRELATION = {CORRELATION_KEY ~ TWO_COLUMNS_FUNC}
PLOT = {PLOT_KEY ~ TWO_COLUMNS_FUNC}
HISTOGRAM = {HISTOGRAM_KEY ~ L_PAREN ~ id ~ COMMA ~ POSSIBLE_STR ~ COMMA ~ expr ~ R_PAREN}
DATAFRAME_VALUE_OPS = _{AVERAGE | STD | MODE | VARIANCE | CORRELATION}
DATAFRAME_VOID_OPS = _{PLOT | HISTOGRAM}

RETURN = { RETURN_KEY ~ expr }

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

program = { SOI ~ function* ~ MAIN_FUNCTION ~ EOI }
12 changes: 8 additions & 4 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use pest_consume::Parser;
use pest_consume::match_nodes;
use pest_consume::Parser;

use crate::enums::{Operations, Types};

Expand Down Expand Up @@ -153,10 +153,14 @@ impl LanguageParser {
}
}

pub fn parse(filename: &str, verbose: bool) -> Result<()> {
let file = std::fs::read_to_string(filename).expect(filename);
let inputs = LanguageParser::parse_with_userdata(Rule::program, &file, verbose)?;
fn parse(source: &str, debug: bool) -> Result<()> {
let inputs = LanguageParser::parse_with_userdata(Rule::program, &source, debug)?;
// There should be a single root node in the parsed tree
let input = inputs.single()?;
LanguageParser::program(input)
}

pub fn parse_file(filename: &str, debug: bool) -> Result<()> {
let file = std::fs::read_to_string(filename).expect(filename);
parse(file, debug)
}
39 changes: 39 additions & 0 deletions src/test_parser/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use pest::error::Error;
use pest::Parser;

#[derive(Parser)]
#[grammar = "parser/grammar.pest"] // relative to src
struct MyParser;

fn parse(source: &str) -> Result<(), Error<Rule>> {
if let Err(err) = MyParser::parse(Rule::program, &source) {
Err(err)
} else {
Ok(())
}
}

pub fn parse_file(filename: &str, debug: bool) -> Result<(), Error<Rule>> {
let program = std::fs::read_to_string(filename).expect(filename);
if debug {
println!("Testing {:?}", filename);
}
parse(&program)
}

#[cfg(test)]
mod tests {
use std::fs::read_dir;

use super::*;

#[test]
fn example_files() {
let paths = read_dir("examples").unwrap();
for path in paths {
let file_path = path.expect("File must exist").path();
let file = file_path.to_str().unwrap();
assert!(parse_file(file, true).is_ok());
}
}
}

0 comments on commit ae04be9

Please sign in to comment.