schala/schala-lang/src/reduced_ir/types.rs

136 lines
3.5 KiB
Rust
Raw Normal View History

use std::{collections::HashMap, convert::From, rc::Rc};
2021-10-24 15:59:40 -07:00
use crate::{
builtin::Builtin,
symbol_table::{DefId, SymbolTable},
type_inference::TypeId,
};
2021-10-24 17:57:56 -07:00
//TODO most of these Clone impls only exist to support function application, because the
//tree-walking evaluator moves the reduced IR members.
2021-10-24 15:59:40 -07:00
/// The reduced intermediate representation consists of a list of function definitions, and a block
/// of entrypoint statements. In a repl or script context this can be an arbitrary list of
/// statements, in an executable context will likely just be a pointer to the main() function.
#[derive(Debug)]
pub struct ReducedIR {
pub functions: HashMap<DefId, FunctionDefinition>,
pub entrypoint: Vec<Statement>,
}
impl ReducedIR {
2021-10-24 22:39:11 -07:00
#[allow(dead_code)]
2021-10-24 17:57:56 -07:00
pub fn debug(&self, symbol_table: &SymbolTable) {
2021-10-24 15:59:40 -07:00
println!("Reduced IR:");
println!("Functions:");
println!("-----------");
for (id, callable) in self.functions.iter() {
2021-10-25 13:03:31 -07:00
let name = &symbol_table.lookup_symbol_by_def(id).unwrap().local_name();
2021-10-24 15:59:40 -07:00
println!("{}({}) -> {:?}", id, name, callable);
}
2021-10-26 13:37:03 -07:00
println!();
2021-10-24 15:59:40 -07:00
println!("Entrypoint:");
println!("-----------");
for stmt in self.entrypoint.iter() {
println!("{:?}", stmt);
}
println!("-----------");
}
}
2021-10-24 17:57:56 -07:00
#[derive(Debug, Clone)]
2021-10-24 15:59:40 -07:00
pub enum Statement {
Expression(Expression),
Binding { id: DefId, constant: bool, expr: Expression },
2021-11-01 00:14:15 -07:00
Return(Expression),
Continue,
Break,
2021-10-24 15:59:40 -07:00
}
2021-10-24 17:57:56 -07:00
#[derive(Debug, Clone)]
2021-10-24 15:59:40 -07:00
pub enum Expression {
Literal(Literal),
Tuple(Vec<Expression>),
2021-11-02 21:19:29 -07:00
List(Vec<Expression>),
2021-10-25 14:37:12 -07:00
Lookup(Lookup),
Assign { lval: DefId, rval: Box<Expression> },
2021-10-30 22:45:08 -07:00
Access { name: String, expr: Box<Expression> },
Callable(Callable),
Call { f: Box<Expression>, args: Vec<Expression> },
Conditional { cond: Box<Expression>, then_clause: Vec<Statement>, else_clause: Vec<Statement> },
CaseMatch { cond: Box<Expression>, alternatives: Vec<Alternative> },
2021-11-01 12:35:25 -07:00
Loop { cond: Box<Expression>, statements: Vec<Statement> },
2021-11-03 00:01:12 -07:00
Index { indexee: Box<Expression>, indexer: Box<Expression> },
2021-10-24 15:59:40 -07:00
ReductionError(String),
}
impl Expression {
pub fn unit() -> Self {
Expression::Tuple(vec![])
}
}
#[derive(Debug)]
pub struct FunctionDefinition {
pub body: Vec<Statement>,
2021-10-24 15:59:40 -07:00
}
#[derive(Debug, Clone)]
pub enum Callable {
2021-10-24 15:59:40 -07:00
Builtin(Builtin),
2021-10-24 18:59:00 -07:00
UserDefined(DefId),
Lambda { arity: u8, body: Vec<Statement> },
DataConstructor { type_id: TypeId, tag: u32 },
2021-10-29 22:03:34 -07:00
RecordConstructor { type_id: TypeId, tag: u32, field_order: Vec<String> },
2021-10-24 15:59:40 -07:00
}
2021-10-24 17:57:56 -07:00
#[derive(Debug, Clone)]
2021-10-24 15:59:40 -07:00
pub enum Lookup {
2021-10-25 14:37:12 -07:00
LocalVar(DefId),
GlobalVar(DefId),
Function(DefId),
2021-10-24 17:57:56 -07:00
Param(u8),
2021-10-24 15:59:40 -07:00
}
2021-10-25 23:01:32 -07:00
#[derive(Debug, Clone, PartialEq)]
2021-10-24 15:59:40 -07:00
pub enum Literal {
Nat(u64),
Int(i64),
Float(f64),
Bool(bool),
StringLit(Rc<String>),
}
2021-10-25 21:19:26 -07:00
#[derive(Debug, Clone)]
pub struct Alternative {
pub pattern: Pattern,
2021-10-25 21:19:26 -07:00
pub item: Vec<Statement>,
}
#[derive(Debug, Clone)]
pub enum Pattern {
Tuple { subpatterns: Vec<Pattern>, tag: Option<u32> },
2021-11-01 13:46:38 -07:00
Record { tag: u32, subpatterns: Vec<(Rc<String>, Pattern)> },
Literal(Literal),
Ignored,
Binding(DefId),
}
2021-10-26 13:12:24 -07:00
#[allow(dead_code)]
#[derive(Debug)]
pub struct PatternError {
msg: String,
}
impl From<&str> for PatternError {
fn from(s: &str) -> Self {
Self { msg: s.to_string() }
}
}
2021-10-25 23:01:32 -07:00
impl From<String> for PatternError {
fn from(msg: String) -> Self {
Self { msg }
}
}