This commit is contained in:
Michael Zhang 2024-12-02 04:38:08 -06:00
parent 4249d67308
commit eebcbf8d1e
6 changed files with 112 additions and 74 deletions

30
README.md Normal file
View file

@ -0,0 +1,30 @@
# AOC Lang
This is a language I am writing to complete Advent of Code 2024.
See `examples/*.aoc` for the programs.
Goals/Features:
- Interpreter
- Lambda functions
Future goals/features:
- Fix the parser
- Error reporting (i.e some kind of graph?)
- Language features
- Records
- Enums
- Type checking
- Effects
- Compiler
- Codegen
- x86
- ARM
- Garbage collector
- JIT
- REPL
I will probably not finish during AOC 2024.
I'll continue working on it over time though.

View file

@ -0,0 +1,76 @@
use std::collections::HashSet;
use crate::ast::{Expr, Stmt};
pub fn free_variables_stmt_rec(
st: &Stmt,
ctx: &mut HashSet<String>,
s: &mut HashSet<String>,
) {
match st {
Stmt::Input(_, _) => {}
Stmt::Let(n, expr) => {
free_variables_expr_rec(expr, ctx, s);
ctx.insert(n.to_owned());
}
Stmt::Print(expr) => free_variables_expr_rec(expr, ctx, s),
}
}
pub fn free_variables_expr_rec(
e: &Expr,
ctx: &mut HashSet<String>,
s: &mut HashSet<String>,
) {
match e {
Expr::Block(vec, expr) => {
for v in vec {
free_variables_stmt_rec(v, ctx, s);
}
if let Some(expr) = expr {
free_variables_expr_rec(expr, ctx, s);
}
}
Expr::Array(vec) => {
for v in vec {
free_variables_expr_rec(v, ctx, s);
}
}
Expr::Bool(_) => {}
Expr::Int(_) => {}
Expr::Ident(n) => {
if !ctx.contains(n) {
s.insert(n.to_owned());
}
}
Expr::IfThenElse(expr, expr1, expr2) => {
free_variables_expr_rec(expr, ctx, s);
free_variables_expr_rec(expr1, ctx, s);
free_variables_expr_rec(expr2, ctx, s);
}
Expr::BinOp(expr, _, expr1) => {
free_variables_expr_rec(expr, ctx, s);
free_variables_expr_rec(expr1, ctx, s);
}
Expr::Field(expr, _) => {
free_variables_expr_rec(expr, ctx, s);
}
Expr::Call(expr, vec) => {
free_variables_expr_rec(expr, ctx, s);
for v in vec {
free_variables_expr_rec(v, ctx, s);
}
}
Expr::Index(expr, expr1) => {
free_variables_expr_rec(expr, ctx, s);
free_variables_expr_rec(expr1, ctx, s);
}
Expr::Lambda(vec, expr) => {
let mut new_set = ctx.clone();
for v in vec {
new_set.insert(v.to_owned());
}
free_variables_expr_rec(expr, &mut new_set, s);
}
}
}

1
src/algo/mod.rs Normal file
View file

@ -0,0 +1 @@
pub mod free_variables;

View file

@ -7,7 +7,10 @@ use std::{
use anyhow::{bail, ensure, Context, Result};
use once_cell::unsync::OnceCell;
use crate::ast::{Expr, Op, Stmt, Value};
use crate::{
algo::free_variables::free_variables_expr_rec,
ast::{Expr, Op, Stmt, Value},
};
thread_local! {
static PARENT: OnceCell<PathBuf> = OnceCell::new();
@ -324,76 +327,3 @@ fn insert_builtins(ctx: &mut HashMap<String, Value>) {
}
ctx.insert("sum".to_owned(), Value::Builtin(sum));
}
fn free_variables_stmt_rec(
st: &Stmt,
ctx: &mut HashSet<String>,
s: &mut HashSet<String>,
) {
match st {
Stmt::Input(_, _) => {}
Stmt::Let(n, expr) => {
free_variables_expr_rec(expr, ctx, s);
ctx.insert(n.to_owned());
}
Stmt::Print(expr) => free_variables_expr_rec(expr, ctx, s),
}
}
fn free_variables_expr_rec(
e: &Expr,
ctx: &mut HashSet<String>,
s: &mut HashSet<String>,
) {
match e {
Expr::Block(vec, expr) => {
for v in vec {
free_variables_stmt_rec(v, ctx, s);
}
if let Some(expr) = expr {
free_variables_expr_rec(expr, ctx, s);
}
}
Expr::Array(vec) => {
for v in vec {
free_variables_expr_rec(v, ctx, s);
}
}
Expr::Bool(_) => {}
Expr::Int(_) => {}
Expr::Ident(n) => {
if !ctx.contains(n) {
s.insert(n.to_owned());
}
}
Expr::IfThenElse(expr, expr1, expr2) => {
free_variables_expr_rec(expr, ctx, s);
free_variables_expr_rec(expr1, ctx, s);
free_variables_expr_rec(expr2, ctx, s);
}
Expr::BinOp(expr, _, expr1) => {
free_variables_expr_rec(expr, ctx, s);
free_variables_expr_rec(expr1, ctx, s);
}
Expr::Field(expr, _) => {
free_variables_expr_rec(expr, ctx, s);
}
Expr::Call(expr, vec) => {
free_variables_expr_rec(expr, ctx, s);
for v in vec {
free_variables_expr_rec(v, ctx, s);
}
}
Expr::Index(expr, expr1) => {
free_variables_expr_rec(expr, ctx, s);
free_variables_expr_rec(expr1, ctx, s);
}
Expr::Lambda(vec, expr) => {
let mut new_set = ctx.clone();
for v in vec {
new_set.insert(v.to_owned());
}
free_variables_expr_rec(expr, &mut new_set, s);
}
}
}

View file

@ -1,3 +1,4 @@
mod algo;
mod arch;
mod ast;
mod compiler;