added evaluating, basically just added support for adding and

subtracting
This commit is contained in:
2026-07-10 15:11:43 -05:00
parent 96527be678
commit 68955312bb
10 changed files with 106 additions and 33 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
{
"cSpell.words": ["Peekable"]
"cSpell.words": ["binop", "Peekable"]
}
-28
View File
@@ -1,28 +0,0 @@
use std::process;
use crate::parser::Parser;
pub fn repl() {
// Read-Eval-Print Loop
use std::io::{self, Write};
println!("Welcome to the Riv Lang REPL! Type 'exit' to quit.");
loop {
print!("> ");
io::stdout().flush().unwrap();
let mut input = String::new();
io::stdin().read_line(&mut input).unwrap();
let input = input.trim().to_string();
if input == "exit" {
process::exit(0);
}
let program = Parser::new(input).produce_ast();
println!("{:#?}", program);
}
}
View File
+3
View File
@@ -0,0 +1,3 @@
pub mod ast;
pub mod lexer;
pub mod parser;
+34 -4
View File
@@ -1,9 +1,39 @@
use clap::Parser;
use std::process;
mod ast;
mod frontend;
mod lexer;
mod parser;
use frontend::ast;
use frontend::lexer;
use frontend::parser;
mod runtime;
use runtime::interpreter::evaluate;
pub fn repl() {
// Read-Eval-Print Loop
use std::io::{self, Write};
println!("Welcome to the Riv Lang REPL! Type 'exit' to quit.");
loop {
print!("> ");
io::stdout().flush().unwrap();
let mut input = String::new();
io::stdin().read_line(&mut input).unwrap();
let input = input.trim().to_string();
if input == "exit" {
process::exit(0);
}
let program = parser::Parser::new(input).produce_ast();
let result = evaluate(frontend::ast::NodeType::Program(program));
println!("{:#?}", result);
}
}
#[derive(clap::Parser)]
struct CLI {
@@ -20,7 +50,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let cli = CLI::parse();
if cli.repl {
frontend::repl();
repl();
} else if let Some(file_path) = cli.file {
let source_code = std::fs::read_to_string(file_path)?;
let mut parser = parser::Parser::new(source_code);
+61
View File
@@ -0,0 +1,61 @@
use std::process;
use crate::frontend::ast::{BinaryExpr, NodeType, Program};
use crate::runtime::values::ValueType;
fn eval_program(program: Program) -> ValueType {
// Initialize with your equivalent of NullVal
let mut last_evaluated = ValueType::Null;
// Iterate through each statement in the program body
for statement in program.body {
last_evaluated = evaluate(statement);
}
last_evaluated
}
fn eval_binop(binop: BinaryExpr) -> ValueType {
let lhs = evaluate(*binop.left);
let rhs = evaluate(*binop.right);
match (&lhs, &rhs) {
(ValueType::Number(l), ValueType::Number(r)) => eval_num_binop(*l, *r, binop.operator),
_ => ValueType::Null,
}
}
fn eval_num_binop(lhs: f64, rhs: f64, operator: String) -> ValueType {
let result: f64;
match operator.as_str() {
"+" => result = lhs + rhs,
"-" => result = lhs - rhs,
"*" => result = lhs * rhs,
// TODO: Handle division by zero
"/" => result = lhs / rhs,
"%" => result = lhs % rhs,
_ => {
eprintln!("Unknown operator: {}", operator);
process::exit(1);
}
}
ValueType::Number(result)
}
pub fn evaluate(node: NodeType) -> ValueType {
match node {
NodeType::NumericLiteral(n) => ValueType::Number(n.value),
NodeType::NullLiteral(_) => ValueType::Null,
NodeType::BinaryExpr(e) => eval_binop(e),
NodeType::Program(p) => eval_program(p),
_ => {
eprintln!(
"Evaluation for node type {:#?} is not implemented yet.",
node
);
process::exit(1);
}
}
}
+2
View File
@@ -0,0 +1,2 @@
pub mod interpreter;
pub mod values;
+5
View File
@@ -0,0 +1,5 @@
#[derive(Debug, Clone, PartialEq)]
pub enum ValueType {
Null,
Number(f64),
}