summaryrefslogtreecommitdiff
path: root/src/simple.rs
blob: f71da464319b6bf0f19f2edc5ace64886fa237a9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// Simple bidirectional type checking

use crate::ast::*;

pub fn infer(context: Context, expression: Expression) {
    todo!();
}

pub fn check(context: Context, expression: Expression) {
    todo!();
}

/// Evaluates an expression given a context (of variables) to a term.
/// Panics on non-evaluatable code.
pub fn execute(context: Context, expression: Expression) -> Term {
    match expression {
        Expression::Annotation { expr, .. } => return execute(context, *expr),
        Expression::Constant { term } => return term,
        Expression::Variable { id } => return context[&id],
        Expression::Abstraction { .. } => panic!(),
        Expression::Application { func, arg } => {
            match *func {
                Expression::Abstraction { param, func } => {
                    let mut context = context;
                    context.insert(param, execute(context.clone(), *arg));
                    return execute(context, *func);
                },
                _ => panic!()
            }
        },
        Expression::Conditional { if_cond, if_then, if_else } => {
            match execute(context.clone(), *if_cond).val {
                1 => execute(context, *if_then),
                0 => execute(context, *if_else),
                _ => panic!()
            }
        },
    }
}

// intentionally small: i want to run into errors
/// assumption: the count is instantiated to zero
fn uniquify(count: &mut u8) -> String {
    *count += 1;
    if *count == 0 {
        panic!("we've overflowed!");
    } else {
        return String::from(format!("{:X}", count));
    }
}