regions-mock-tcx.rs 3.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

N
Niko Matsakis 已提交
11 12
// xfail-fast `use` standards don't resolve

13 14 15 16 17 18
// Test a sample usage pattern for regions. Makes use of the
// following features:
//
// - Multiple lifetime parameters
// - Arenas

D
David Manescu 已提交
19
extern mod arena;
20

D
David Manescu 已提交
21
use arena::Arena;
22 23 24 25 26 27 28 29 30 31 32
use std::hashmap::HashMap;
use std::cast;
use std::libc;
use std::mem;

type Type<'tcx> = &'tcx TypeStructure<'tcx>;

enum TypeStructure<'tcx> {
    TypeInt,
    TypeFunction(Type<'tcx>, Type<'tcx>),
}
33 34 35 36 37 38 39 40 41
impl<'tcx> Eq for TypeStructure<'tcx> {
    fn eq(&self, other: &TypeStructure<'tcx>) -> bool {
        match (*self, *other) {
            (TypeInt, TypeInt) => true,
            (TypeFunction(s_a, s_b), TypeFunction(o_a, o_b)) => *s_a == *o_a && *s_b == *o_b,
            _ => false
        }
    }
}
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129

struct TypeContext<'tcx, 'ast> {
    ty_arena: &'tcx Arena,
    types: ~[Type<'tcx>],
    type_table: HashMap<NodeId, Type<'tcx>>,

    ast_arena: &'ast Arena,
    ast_counter: uint,
}

impl<'tcx,'ast> TypeContext<'tcx, 'ast> {
    fn new(ty_arena: &'tcx Arena, ast_arena: &'ast Arena)
           -> TypeContext<'tcx, 'ast> {
        TypeContext { ty_arena: ty_arena,
                      types: ~[],
                      type_table: HashMap::new(),

                      ast_arena: ast_arena,
                      ast_counter: 0 }
    }

    fn add_type(&mut self, s: TypeStructure<'tcx>) -> Type<'tcx> {
        for &ty in self.types.iter() {
            if *ty == s {
                return ty;
            }
        }

        let ty = self.ty_arena.alloc(|| s);
        self.types.push(ty);
        ty
    }

    fn set_type(&mut self, id: NodeId, ty: Type<'tcx>) -> Type<'tcx> {
        self.type_table.insert(id, ty);
        ty
    }

    fn ast(&mut self, a: AstKind<'ast>) -> Ast<'ast> {
        let id = self.ast_counter;
        self.ast_counter += 1;
        self.ast_arena.alloc(|| AstStructure { id: NodeId {id:id}, kind: a })
    }
}

#[deriving(Eq, IterBytes)]
struct NodeId {
    id: uint
}

type Ast<'ast> = &'ast AstStructure<'ast>;

struct AstStructure<'ast> {
    id: NodeId,
    kind: AstKind<'ast>
}

enum AstKind<'ast> {
    ExprInt,
    ExprVar(uint),
    ExprLambda(Ast<'ast>),
}

fn compute_types<'tcx,'ast>(tcx: &mut TypeContext<'tcx,'ast>,
                            ast: Ast<'ast>) -> Type<'tcx>
{
    match ast.kind {
        ExprInt | ExprVar(_) => {
            let ty = tcx.add_type(TypeInt);
            tcx.set_type(ast.id, ty)
        }
        ExprLambda(ast) => {
            let arg_ty = tcx.add_type(TypeInt);
            let body_ty = compute_types(tcx, ast);
            let lambda_ty = tcx.add_type(TypeFunction(arg_ty, body_ty));
            tcx.set_type(ast.id, lambda_ty)
        }
    }
}

pub fn main() {
    let ty_arena = arena::Arena::new();
    let ast_arena = arena::Arena::new();
    let mut tcx = TypeContext::new(&ty_arena, &ast_arena);
    let ast = tcx.ast(ExprInt);
    let ty = compute_types(&mut tcx, ast);
    assert_eq!(*ty, TypeInt);
}