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

154 lines
3.3 KiB
Rust

use std::collections::HashMap;
use std::rc::Rc;
use std::convert::From;
use crate::builtin::Builtin;
use crate::symbol_table::{DefId, SymbolTable};
use crate::typechecking::TypeId;
//TODO most of these Clone impls only exist to support function application, because the
//tree-walking evaluator moves the reduced IR members.
/// 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 {
#[allow(dead_code)]
pub fn debug(&self, symbol_table: &SymbolTable) {
println!("Reduced IR:");
println!("Functions:");
println!("-----------");
for (id, callable) in self.functions.iter() {
let name = &symbol_table.lookup_symbol_by_def(id).unwrap().local_name();
println!("{}({}) -> {:?}", id, name, callable);
}
println!("");
println!("Entrypoint:");
println!("-----------");
for stmt in self.entrypoint.iter() {
println!("{:?}", stmt);
}
println!("-----------");
}
}
#[derive(Debug, Clone)]
pub enum Statement {
Expression(Expression),
Binding {
id: DefId,
constant: bool,
expr: Expression
},
}
#[derive(Debug, Clone)]
pub enum Expression {
Literal(Literal),
Tuple(Vec<Expression>),
Lookup(Lookup),
Assign {
lval: DefId,
rval: 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>,
},
ReductionError(String),
}
impl Expression {
pub fn unit() -> Self {
Expression::Tuple(vec![])
}
}
#[derive(Debug)]
pub struct FunctionDefinition {
pub body: Vec<Statement>
}
#[derive(Debug, Clone)]
pub enum Callable {
Builtin(Builtin),
UserDefined(DefId),
Lambda {
arity: u8,
body: Vec<Statement>
},
DataConstructor {
type_id: TypeId,
arity: u32,
tag: u32
},
}
#[derive(Debug, Clone)]
pub enum Lookup {
LocalVar(DefId),
GlobalVar(DefId),
Function(DefId),
Param(u8),
}
#[derive(Debug, Clone, PartialEq)]
pub enum Literal {
Nat(u64),
Int(i64),
Float(f64),
Bool(bool),
StringLit(Rc<String>),
}
#[derive(Debug, Clone)]
pub struct Alternative {
pub pattern: Pattern,
pub item: Vec<Statement>,
}
#[derive(Debug, Clone)]
pub enum Pattern {
Tuple {
subpatterns: Vec<Pattern>,
tag: Option<u32>,
},
Literal(Literal),
Ignored,
Binding(DefId)
}
#[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() }
}
}
impl From<String> for PatternError {
fn from(msg: String) -> Self {
Self { msg }
}
}