Skip to content

Instantly share code, notes, and snippets.

@rightfold

rightfold/.rs Secret

Last active October 9, 2015 09:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rightfold/05c5fff68ed72f21adf5 to your computer and use it in GitHub Desktop.
Save rightfold/05c5fff68ed72f21adf5 to your computer and use it in GitHub Desktop.
use std::collections::HashMap;
#[derive(Eq, PartialEq)]
struct Name {
module: Vec<String>,
name: String,
}
#[derive(Eq, PartialEq)]
enum Type {
Erroneous,
Int,
Struct(HashMap<String, Type>),
Named(Name, Box<Type>),
}
impl Type {
fn is_erroneous(&self) -> bool {
match *self {
Type::Erroneous => true,
Type::Int => false,
Type::Struct(ref fields) => fields.values().any(Type::is_erroneous),
Type::Named(_, ref underlying_type) => underlying_type.is_erroneous(),
}
}
}
enum Expr {
Int(i64),
Add(Box<Expr>, Box<Expr>),
}
enum Diagnostic {
TypeMismatch(Type, Type),
}
fn type_check<EmitDiagnostic>(expr: &Expr, emit_diagnostic: &EmitDiagnostic) -> Type
where EmitDiagnostic: Fn(Diagnostic) -> () {
match *expr {
Expr::Int(_) => Type::Int,
Expr::Add(ref a, ref b) => {
let a_type = type_check(expr, emit_diagnostic);
let b_type = type_check(expr, emit_diagnostic);
if a_type != Type::Int {
if !a_type.is_erroneous() {
emit_diagnostic(Diagnostic::TypeMismatch(a_type, Type::Int));
}
Type::Erroneous
} else if b_type != Type::Int {
if !b_type.is_erroneous() {
emit_diagnostic(Diagnostic::TypeMismatch(b_type, Type::Int));
}
Type::Erroneous
} else {
Type::Int
}
},
}
}
fn main() { }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment