<commit_before>use std::collections::HashMap;

use fixpoint::{Fix, fix_result};

use super::term::{Primitive, Term};

#[derive (Debug, PartialEq, Eq)]
pub enum ReferenceError { NotFound(String) }

#[derive (Debug, PartialEq, Eq)]
pub enum TypeError { NotAFunction(Primitive) }

#[derive (Debug, PartialEq, Eq)]
pub enum EvalError {
    ReferenceError(ReferenceError),
    TypeError(TypeError),
    StackOverflow
}

pub struct Context(HashMap<String, Term>);

impl Context {

    pub fn new() -> Context {
        Context(HashMap::new())
    }

    pub fn lookup(&mut self, id: String) -> Result<Term, ReferenceError> {
        self.0.remove(&id).ok_or(ReferenceError::NotFound(id))
    }

    pub fn bind(&mut self, id: String, term: Term) {
        self.0.insert(id, term);
    }

}

struct ArgStack(Vec<Box<Term>>);

impl ArgStack {

    fn new() -> ArgStack {
        ArgStack(Vec::new())
    }

    fn push(&mut self, arg_box: Box<Term>) {
        self.0.push(arg_box)
    }

    fn pop(&mut self) -> Option<Box<Term>> {
        self.0.pop()
    }

    fn unwind(&mut self, term: Term) -> Fix<Term> {
        match self.pop() {
            Option::None => Fix::Fix(term),
            Option::Some(arg_box) => Fix::Pro(Term::App(Box::new(term), arg_box))
        }
    }

}

type EvalResult = Result<Fix<Term>, EvalError>;

fn eval_shallow(ctx: &mut Context, args: &mut ArgStack, term: Term) -> EvalResult {
    match term {
        Term::Val(val) => Result::Ok(Fix::Fix(Term::Val(val))),
        Term::Abs(id, term_box) => Result::Ok(Fix::Fix(Term::Abs(id, term_box))),
        Term::Ref(id) => match ctx.lookup(id) {
            Result::Err(err) => Result::Err(EvalError::ReferenceError(err)),
            Result::Ok(term) => Result::Ok(Fix::Pro(term))
        },
        Term::App(fun_box, arg_box) => {
            let fun: Term = *fun_box;
            match fun {
                Term::Val(val) => {
                    Result::Err(EvalError::TypeError(TypeError::NotAFunction(val)))
                },
                Term::Abs(id, term_box) => {
                    ctx.bind(id, *arg_box);
                    Result::Ok(Fix::Pro(*term_box))
                },
                fun_term => {
                    args.push(arg_box);
                    Result::Ok(Fix::Pro(fun_term))
                }
            }
        }
    }
}

pub fn eval(ctx: &mut Context, term: Term) -> Result<Term, EvalError> {
    // find the head normal form of the term,
    // which is equivalent to the fixpoint of
    // the eval_shallow function
    let mut args = ArgStack::new();
    fix_result(term, |term| {
        eval_shallow(ctx, &mut args, term).map(|fix| match fix {
            Fix::Pro(term) => Fix::Pro(term),
            Fix::Fix(term) => args.unwind(term)
        })
    })
}

#[test]
fn eval_val() {
    let mut c = Context::new();
    let x = eval(&mut c, Term::val_int(42));
    assert_eq!(x, Result::Ok(Term::val_int(42)));
}

#[test]
fn eval_id() {
    let mut c = Context::new();
    let x = eval(&mut c,
        Term::app(
            Term::fun(
                "x".to_string(),
                Term::id("x".to_string())
            ),
            Term::val_int(42)
        )
    );
    assert_eq!(x, Result::Ok(Term::val_int(42)));
}
<commit_msg>simplify lookup result handling<commit_after>use std::collections::HashMap;

use fixpoint::{Fix, fix_result};

use super::term::{Primitive, Term};

#[derive (Debug, PartialEq, Eq)]
pub enum ReferenceError { NotFound(String) }

#[derive (Debug, PartialEq, Eq)]
pub enum TypeError { NotAFunction(Primitive) }

#[derive (Debug, PartialEq, Eq)]
pub enum EvalError {
    ReferenceError(ReferenceError),
    TypeError(TypeError),
    StackOverflow
}

pub struct Context(HashMap<String, Term>);

impl Context {

    pub fn new() -> Context {
        Context(HashMap::new())
    }

    pub fn lookup(&mut self, id: String) -> Result<Term, ReferenceError> {
        self.0.remove(&id).ok_or(ReferenceError::NotFound(id))
    }

    pub fn bind(&mut self, id: String, term: Term) {
        self.0.insert(id, term);
    }

}

struct ArgStack(Vec<Box<Term>>);

impl ArgStack {

    fn new() -> ArgStack {
        ArgStack(Vec::new())
    }

    fn push(&mut self, arg_box: Box<Term>) {
        self.0.push(arg_box)
    }

    fn pop(&mut self) -> Option<Box<Term>> {
        self.0.pop()
    }

    fn unwind(&mut self, term: Term) -> Fix<Term> {
        match self.pop() {
            Option::None => Fix::Fix(term),
            Option::Some(arg_box) => Fix::Pro(Term::App(Box::new(term), arg_box))
        }
    }

}

type EvalResult = Result<Fix<Term>, EvalError>;

fn eval_shallow(ctx: &mut Context, args: &mut ArgStack, term: Term) -> EvalResult {
    match term {
        Term::Val(val) => Result::Ok(Fix::Fix(Term::Val(val))),
        Term::Abs(id, term_box) => Result::Ok(Fix::Fix(Term::Abs(id, term_box))),
        Term::Ref(id) => ctx.lookup(id).map(Fix::Pro).map_err(EvalError::ReferenceError),
        Term::App(fun_box, arg_box) => {
            let fun: Term = *fun_box;
            match fun {
                Term::Val(val) => {
                    Result::Err(EvalError::TypeError(TypeError::NotAFunction(val)))
                },
                Term::Abs(id, term_box) => {
                    ctx.bind(id, *arg_box);
                    Result::Ok(Fix::Pro(*term_box))
                },
                fun_term => {
                    args.push(arg_box);
                    Result::Ok(Fix::Pro(fun_term))
                }
            }
        }
    }
}

pub fn eval(ctx: &mut Context, term: Term) -> Result<Term, EvalError> {
    // find the head normal form of the term,
    // which is equivalent to the fixpoint of
    // the eval_shallow function
    let mut args = ArgStack::new();
    fix_result(term, |term| {
        eval_shallow(ctx, &mut args, term).map(|fix| match fix {
            Fix::Pro(term) => Fix::Pro(term),
            Fix::Fix(term) => args.unwind(term)
        })
    })
}

#[test]
fn eval_val() {
    let mut c = Context::new();
    let x = eval(&mut c, Term::val_int(42));
    assert_eq!(x, Result::Ok(Term::val_int(42)));
}

#[test]
fn eval_id() {
    let mut c = Context::new();
    let x = eval(&mut c,
        Term::app(
            Term::fun(
                "x".to_string(),
                Term::id("x".to_string())
            ),
            Term::val_int(42)
        )
    );
    assert_eq!(x, Result::Ok(Term::val_int(42)));
}
<|endoftext|>


<commit_before>// Copyright 2018 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.

use spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
use spec::abi::{Abi};

pub fn target() -> TargetResult {
    Ok(Target {
        data_layout: "e-m:e-p:32:32-i64:64-n32-S128".to_string(),
        llvm_target: "riscv32".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "32".to_string(),
        target_c_int_width: "32".to_string(),
        target_os: "none".to_string(),
        target_env: "".to_string(),
        target_vendor: "unknown".to_string(),
        arch: "riscv32".to_string(),
        linker_flavor: LinkerFlavor::Ld,

        options: TargetOptions {
            linker: Some("riscv32-unknown-elf-ld".to_string()),
            cpu: "generic-rv32".to_string(),
            max_atomic_width: Some(32),
            atomic_cas: false, // incomplete +a extension
            features: "+m,+a".to_string(), // disable +c extension
            executables: true,
            panic_strategy: PanicStrategy::Abort,
            relocation_model: "static".to_string(),
            abi_blacklist: vec![
                Abi::Cdecl,
                Abi::Stdcall,
                Abi::Fastcall,
                Abi::Vectorcall,
                Abi::Thiscall,
                Abi::Aapcs,
                Abi::Win64,
                Abi::SysV64,
                Abi::PtxKernel,
                Abi::Msp430Interrupt,
                Abi::X86Interrupt,
            ],
            .. Default::default()
        },
    })
}
<commit_msg>Rollup merge of #53139 - danc86:riscv-no-gdb-scripts, r=petrochenkov<commit_after>// Copyright 2018 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.

use spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
use spec::abi::{Abi};

pub fn target() -> TargetResult {
    Ok(Target {
        data_layout: "e-m:e-p:32:32-i64:64-n32-S128".to_string(),
        llvm_target: "riscv32".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "32".to_string(),
        target_c_int_width: "32".to_string(),
        target_os: "none".to_string(),
        target_env: "".to_string(),
        target_vendor: "unknown".to_string(),
        arch: "riscv32".to_string(),
        linker_flavor: LinkerFlavor::Ld,

        options: TargetOptions {
            linker: Some("riscv32-unknown-elf-ld".to_string()),
            cpu: "generic-rv32".to_string(),
            max_atomic_width: Some(32),
            atomic_cas: false, // incomplete +a extension
            features: "+m,+a".to_string(), // disable +c extension
            executables: true,
            panic_strategy: PanicStrategy::Abort,
            relocation_model: "static".to_string(),
            emit_debug_gdb_scripts: false,
            abi_blacklist: vec![
                Abi::Cdecl,
                Abi::Stdcall,
                Abi::Fastcall,
                Abi::Vectorcall,
                Abi::Thiscall,
                Abi::Aapcs,
                Abi::Win64,
                Abi::SysV64,
                Abi::PtxKernel,
                Abi::Msp430Interrupt,
                Abi::X86Interrupt,
            ],
            .. Default::default()
        },
    })
}
<|endoftext|>


<commit_before>use libc::*;
use std::option::Some;
use std::cast;
use std::str;
use std::kinds::marker::NoSend;

use sync::{Arc, Mutex};

use ffi::*;

use internal::events::*;
use internal::keycodes::*;

pub mod external
{
	pub use super::Core;
}

pub static mut dummy_target: *mut ALLEGRO_BITMAP = 0 as *mut ALLEGRO_BITMAP;

pub struct Core
{
	keyboard_event_source: Option<EventSource>,
	mouse_event_source: Option<EventSource>,
	joystick_event_source: Option<EventSource>,
	mutex: Arc<Mutex<()>>,
	no_send_marker: NoSend,
}

impl Core
{
	pub fn init() -> Result<Core, ~str>
	{
		use sync::one::{Once, ONCE_INIT};
		static mut run_once: Once = ONCE_INIT;

		let mut res = Err(~"Already initialized.");
		unsafe
		{
			run_once.doit(||
			{
				res = if al_install_system(ALLEGRO_VERSION_INT as c_int, None) != 0
				{
					al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP as i32);
					dummy_target = al_create_bitmap(1, 1);
					al_set_new_bitmap_flags(0);
					if dummy_target.is_null()
					{
						Err(~"Failed to create the dummy target... something is very wrong!")
					}
					else
					{
						al_set_target_bitmap(dummy_target);
						Ok
						(
							Core
							{
								keyboard_event_source: None,
								mouse_event_source: None,
								joystick_event_source: None,
								mutex: Arc::new(Mutex::new(())),
								no_send_marker: NoSend,
							}
						)
					}
				}
				else
				{
					let version = al_get_allegro_version();
					let major = version >> 24;
					let minor = (version >> 16) & 255;
					let revision = (version >> 8) & 255;
					let release = version & 255;

					Err(format!("The system Allegro version ({}.{}.{}.{}) does not match the version of this binding ({}.{}.{}.{})",
					    major, minor, revision, release,
					    ALLEGRO_VERSION, ALLEGRO_SUB_VERSION, ALLEGRO_WIP_VERSION, ALLEGRO_RELEASE_NUMBER))
				};
			});
		}
		res
	}

	pub fn spawn(&self, thread_proc: proc:Send (Core))
	{
		use native;
		let mutex = self.get_core_mutex();
		native::task::spawn(proc()
		{
			thread_proc(Core
			{
				keyboard_event_source: None,
				mouse_event_source: None,
				joystick_event_source: None,
				mutex: mutex,
				no_send_marker: NoSend,
			});
		});
	}

	pub fn get_core_mutex(&self) -> Arc<Mutex<()>>
	{
		self.mutex.clone()
	}

	pub fn get_num_video_adapters(&self) -> i32
	{
		unsafe
		{
			al_get_num_video_adapters() as i32
		}
	}

	pub fn get_monitor_info(&self, adapter: i32) -> Option<(i32, i32, i32, i32)>
	{
		unsafe
		{
			let mut c_info = ALLEGRO_MONITOR_INFO{ x1: 0, y1: 0, x2: 0, y2: 0 };
			let ret = al_get_monitor_info(adapter as c_int, cast::transmute(&mut c_info)) != 0;
			if ret
			{
				Some((c_info.x1 as i32, c_info.y1 as i32, c_info.x2 as i32, c_info.y2 as i32))
			}
			else
			{
				None
			}
		}
	}

	pub fn rest(&self, seconds: f64)
	{
		unsafe
		{
			al_rest(seconds as c_double);
		}
	}

	pub fn install_keyboard(&self) -> bool
	{
		unsafe
		{
			al_install_keyboard() != 0
		}
	}

	pub fn is_keyboard_installed(&self) -> bool
	{
		unsafe
		{
			al_is_keyboard_installed() != 0
		}
	}

	pub fn get_keyboard_event_source<'l>(&'l mut self) -> Option<&'l EventSource>
	{
		if self.keyboard_event_source.is_none() && self.is_keyboard_installed()
		{
			unsafe
			{
				self.keyboard_event_source = Some(new_event_source_ref(al_get_keyboard_event_source()));
			}
		}

		match self.keyboard_event_source
		{
			Some(ref s) => Some(s),
			None => None
		}
	}

	pub fn set_keyboard_leds(&self, leds: KeyModifier) -> bool
	{
		if self.is_keyboard_installed()
		{
			unsafe
			{
				al_set_keyboard_leds(leds.get() as c_int) != 0
			}
		}
		else
		{
			false
		}
	}

	pub fn keycode_to_name(&self, k: key::KeyCode) -> Option<~str>
	{
		if self.is_keyboard_installed()
		{
			unsafe
			{
				Some(str::raw::from_c_str(al_keycode_to_name(k as c_int)))
			}
		}
		else
		{
			None
		}
	}

	pub fn install_mouse(&self) -> bool
	{
		unsafe
		{
			al_install_mouse() != 0
		}
	}

	pub fn is_mouse_installed(&self) -> bool
	{
		unsafe
		{
			al_is_mouse_installed() != 0
		}
	}

	pub fn get_mouse_event_source<'l>(&'l mut self) -> Option<&'l EventSource>
	{
		if self.mouse_event_source.is_none() && self.is_mouse_installed()
		{
			unsafe
			{
				self.mouse_event_source = Some(new_event_source_ref(al_get_mouse_event_source()));
			}
		}

		match self.mouse_event_source
		{
			Some(ref s) => Some(s),
			None => None
		}
	}

	pub fn install_joystick(&self) -> bool
	{
		unsafe
		{
			al_install_joystick() != 0
		}
	}

	pub fn is_joystick_installed(&self) -> bool
	{
		unsafe
		{
			al_is_joystick_installed() != 0
		}
	}

	pub fn get_joystick_event_source<'l>(&'l mut self) -> Option<&'l EventSource>
	{
		if self.joystick_event_source.is_none() && self.is_joystick_installed()
		{
			unsafe
			{
				self.joystick_event_source = Some(new_event_source_ref(al_get_joystick_event_source()));
			}
		}

		match self.joystick_event_source
		{
			Some(ref s) => Some(s),
			None => None
		}
	}

	pub fn reconfigure_joysticks(&self) -> bool
	{
		if self.is_joystick_installed()
		{
			unsafe
			{
				al_reconfigure_joysticks() != 0
			}
		}
		else
		{
			false
		}
	}

	pub fn get_num_joysticks(&self) -> i32
	{
		if self.is_joystick_installed()
		{
			unsafe
			{
				al_get_num_joysticks() as i32
			}
		}
		else
		{
			0
		}
	}
}
<commit_msg>proc syntax changed<commit_after>use libc::*;
use std::option::Some;
use std::cast;
use std::str;
use std::kinds::marker::NoSend;

use sync::{Arc, Mutex};

use ffi::*;

use internal::events::*;
use internal::keycodes::*;

pub mod external
{
	pub use super::Core;
}

pub static mut dummy_target: *mut ALLEGRO_BITMAP = 0 as *mut ALLEGRO_BITMAP;

pub struct Core
{
	keyboard_event_source: Option<EventSource>,
	mouse_event_source: Option<EventSource>,
	joystick_event_source: Option<EventSource>,
	mutex: Arc<Mutex<()>>,
	no_send_marker: NoSend,
}

impl Core
{
	pub fn init() -> Result<Core, ~str>
	{
		use sync::one::{Once, ONCE_INIT};
		static mut run_once: Once = ONCE_INIT;

		let mut res = Err(~"Already initialized.");
		unsafe
		{
			run_once.doit(||
			{
				res = if al_install_system(ALLEGRO_VERSION_INT as c_int, None) != 0
				{
					al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP as i32);
					dummy_target = al_create_bitmap(1, 1);
					al_set_new_bitmap_flags(0);
					if dummy_target.is_null()
					{
						Err(~"Failed to create the dummy target... something is very wrong!")
					}
					else
					{
						al_set_target_bitmap(dummy_target);
						Ok
						(
							Core
							{
								keyboard_event_source: None,
								mouse_event_source: None,
								joystick_event_source: None,
								mutex: Arc::new(Mutex::new(())),
								no_send_marker: NoSend,
							}
						)
					}
				}
				else
				{
					let version = al_get_allegro_version();
					let major = version >> 24;
					let minor = (version >> 16) & 255;
					let revision = (version >> 8) & 255;
					let release = version & 255;

					Err(format!("The system Allegro version ({}.{}.{}.{}) does not match the version of this binding ({}.{}.{}.{})",
					    major, minor, revision, release,
					    ALLEGRO_VERSION, ALLEGRO_SUB_VERSION, ALLEGRO_WIP_VERSION, ALLEGRO_RELEASE_NUMBER))
				};
			});
		}
		res
	}

	pub fn spawn(&self, thread_proc: proc(Core):Send)
	{
		use native;
		let mutex = self.get_core_mutex();
		native::task::spawn(proc()
		{
			thread_proc(Core
			{
				keyboard_event_source: None,
				mouse_event_source: None,
				joystick_event_source: None,
				mutex: mutex,
				no_send_marker: NoSend,
			});
		});
	}

	pub fn get_core_mutex(&self) -> Arc<Mutex<()>>
	{
		self.mutex.clone()
	}

	pub fn get_num_video_adapters(&self) -> i32
	{
		unsafe
		{
			al_get_num_video_adapters() as i32
		}
	}

	pub fn get_monitor_info(&self, adapter: i32) -> Option<(i32, i32, i32, i32)>
	{
		unsafe
		{
			let mut c_info = ALLEGRO_MONITOR_INFO{ x1: 0, y1: 0, x2: 0, y2: 0 };
			let ret = al_get_monitor_info(adapter as c_int, cast::transmute(&mut c_info)) != 0;
			if ret
			{
				Some((c_info.x1 as i32, c_info.y1 as i32, c_info.x2 as i32, c_info.y2 as i32))
			}
			else
			{
				None
			}
		}
	}

	pub fn rest(&self, seconds: f64)
	{
		unsafe
		{
			al_rest(seconds as c_double);
		}
	}

	pub fn install_keyboard(&self) -> bool
	{
		unsafe
		{
			al_install_keyboard() != 0
		}
	}

	pub fn is_keyboard_installed(&self) -> bool
	{
		unsafe
		{
			al_is_keyboard_installed() != 0
		}
	}

	pub fn get_keyboard_event_source<'l>(&'l mut self) -> Option<&'l EventSource>
	{
		if self.keyboard_event_source.is_none() && self.is_keyboard_installed()
		{
			unsafe
			{
				self.keyboard_event_source = Some(new_event_source_ref(al_get_keyboard_event_source()));
			}
		}

		match self.keyboard_event_source
		{
			Some(ref s) => Some(s),
			None => None
		}
	}

	pub fn set_keyboard_leds(&self, leds: KeyModifier) -> bool
	{
		if self.is_keyboard_installed()
		{
			unsafe
			{
				al_set_keyboard_leds(leds.get() as c_int) != 0
			}
		}
		else
		{
			false
		}
	}

	pub fn keycode_to_name(&self, k: key::KeyCode) -> Option<~str>
	{
		if self.is_keyboard_installed()
		{
			unsafe
			{
				Some(str::raw::from_c_str(al_keycode_to_name(k as c_int)))
			}
		}
		else
		{
			None
		}
	}

	pub fn install_mouse(&self) -> bool
	{
		unsafe
		{
			al_install_mouse() != 0
		}
	}

	pub fn is_mouse_installed(&self) -> bool
	{
		unsafe
		{
			al_is_mouse_installed() != 0
		}
	}

	pub fn get_mouse_event_source<'l>(&'l mut self) -> Option<&'l EventSource>
	{
		if self.mouse_event_source.is_none() && self.is_mouse_installed()
		{
			unsafe
			{
				self.mouse_event_source = Some(new_event_source_ref(al_get_mouse_event_source()));
			}
		}

		match self.mouse_event_source
		{
			Some(ref s) => Some(s),
			None => None
		}
	}

	pub fn install_joystick(&self) -> bool
	{
		unsafe
		{
			al_install_joystick() != 0
		}
	}

	pub fn is_joystick_installed(&self) -> bool
	{
		unsafe
		{
			al_is_joystick_installed() != 0
		}
	}

	pub fn get_joystick_event_source<'l>(&'l mut self) -> Option<&'l EventSource>
	{
		if self.joystick_event_source.is_none() && self.is_joystick_installed()
		{
			unsafe
			{
				self.joystick_event_source = Some(new_event_source_ref(al_get_joystick_event_source()));
			}
		}

		match self.joystick_event_source
		{
			Some(ref s) => Some(s),
			None => None
		}
	}

	pub fn reconfigure_joysticks(&self) -> bool
	{
		if self.is_joystick_installed()
		{
			unsafe
			{
				al_reconfigure_joysticks() != 0
			}
		}
		else
		{
			false
		}
	}

	pub fn get_num_joysticks(&self) -> i32
	{
		if self.is_joystick_installed()
		{
			unsafe
			{
				al_get_num_joysticks() as i32
			}
		}
		else
		{
			0
		}
	}
}
<|endoftext|>


<commit_before>use alloc::heap::{Alloc, AllocErr, Layout};
use linked_list_allocator::Heap;
use spin::Mutex;

use paging::ActivePageTable;

static HEAP: Mutex<Option<Heap>> = Mutex::new(None);

pub struct Allocator;

impl Allocator {
    pub unsafe fn init(offset: usize, size: usize) {
        *HEAP.lock() = Some(Heap::new(offset, size));
    }
}

unsafe impl<'a> Alloc for &'a Allocator {
    unsafe fn alloc(&mut self, mut layout: Layout) -> Result<*mut u8, AllocErr> {
        loop {
            let res = if let Some(ref mut heap) = *HEAP.lock() {
                heap.allocate_first_fit(layout)
            } else {
                panic!("__rust_allocate: heap not initialized");
            };

            match res {
                Err(AllocErr::Exhausted { request }) => {
                    layout = request;

                    let size = if let Some(ref heap) = *HEAP.lock() {
                        heap.size()
                    } else {
                        panic!("__rust_allocate: heap not initialized");
                    };

                    println!("Expand heap at {} MB by {} MB", size/1024/1024, ::KERNEL_HEAP_SIZE/1024/1024);

                    super::map_heap(&mut ActivePageTable::new(), ::KERNEL_HEAP_OFFSET + size, ::KERNEL_HEAP_SIZE);

                    if let Some(ref mut heap) = *HEAP.lock() {
                        heap.extend(::KERNEL_HEAP_SIZE);
                    } else {
                        panic!("__rust_allocate: heap not initialized");
                    }
                },
                other => return other,
            }
        }
    }

    unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
        if let Some(ref mut heap) = *HEAP.lock() {
            heap.deallocate(ptr, layout)
        } else {
            panic!("__rust_deallocate: heap not initialized");
        }
    }

    fn oom(&mut self, error: AllocErr) -> ! {
        panic!("Out of memory: {:?}", error);
    }

    fn usable_size(&self, layout: &Layout) -> (usize, usize) {
        if let Some(ref mut heap) = *HEAP.lock() {
            heap.usable_size(layout)
        } else {
            panic!("__rust_usable_size: heap not initialized");
        }
    }
}
<commit_msg>Remove debug message<commit_after>use alloc::heap::{Alloc, AllocErr, Layout};
use linked_list_allocator::Heap;
use spin::Mutex;

use paging::ActivePageTable;

static HEAP: Mutex<Option<Heap>> = Mutex::new(None);

pub struct Allocator;

impl Allocator {
    pub unsafe fn init(offset: usize, size: usize) {
        *HEAP.lock() = Some(Heap::new(offset, size));
    }
}

unsafe impl<'a> Alloc for &'a Allocator {
    unsafe fn alloc(&mut self, mut layout: Layout) -> Result<*mut u8, AllocErr> {
        loop {
            let res = if let Some(ref mut heap) = *HEAP.lock() {
                heap.allocate_first_fit(layout)
            } else {
                panic!("__rust_allocate: heap not initialized");
            };

            match res {
                Err(AllocErr::Exhausted { request }) => {
                    layout = request;

                    let size = if let Some(ref heap) = *HEAP.lock() {
                        heap.size()
                    } else {
                        panic!("__rust_allocate: heap not initialized");
                    };

                    super::map_heap(&mut ActivePageTable::new(), ::KERNEL_HEAP_OFFSET + size, ::KERNEL_HEAP_SIZE);

                    if let Some(ref mut heap) = *HEAP.lock() {
                        heap.extend(::KERNEL_HEAP_SIZE);
                    } else {
                        panic!("__rust_allocate: heap not initialized");
                    }
                },
                other => return other,
            }
        }
    }

    unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
        if let Some(ref mut heap) = *HEAP.lock() {
            heap.deallocate(ptr, layout)
        } else {
            panic!("__rust_deallocate: heap not initialized");
        }
    }

    fn oom(&mut self, error: AllocErr) -> ! {
        panic!("Out of memory: {:?}", error);
    }

    fn usable_size(&self, layout: &Layout) -> (usize, usize) {
        if let Some(ref mut heap) = *HEAP.lock() {
            heap.usable_size(layout)
        } else {
            panic!("__rust_usable_size: heap not initialized");
        }
    }
}
<|endoftext|>


<commit_before>//! An information element is a portion of a SBD message.
//!
//! Information elements come after the SBD header. They come in many types, including more
//! header-type information and the actual data payload.

use std::io::{Cursor, Read};

use byteorder::{ReadBytesExt, BigEndian};

use {Error, Result};

/// Indicates the success for failure of the SBD session.
enum_from_primitive! {
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum SessionStatus {
    Ok = 0,
    OkMobileTerminatedTooLarge = 1,
    OkLocationUnacceptableQuality = 2,
    Timeout = 10,
    MobileOriginatedTooLarge = 12,
    RFLinkLoss = 13,
    IMEIProtocolAnomaly = 14,
    Prohibited = 15,
    Unknown,
}
}

/// An information element, or IE.
///
/// These are the building blocks of a SBD message. There are several types, generally divided into
/// MO and MT IE's. This general structure just holds the basic IE data, when then can be converted
/// into a specific type of IE.
#[derive(Debug, Default)]
pub struct InformationElement {
    id: u8,
    length: u16,
    contents: Vec<u8>,
}

impl InformationElement {

    /// Reads an information element from something that implements `Read`.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::io::{Read, Seek, SeekFrom};
    /// use std::fs::File;
    /// use sbd::information_element::InformationElement;
    /// let mut file = File::open("data/0-mo.sbd").unwrap();
    /// file.seek(SeekFrom::Start(3)).unwrap();
    /// let readable = file.take(31);
    /// InformationElement::read_from(readable).unwrap();
    /// ```
    pub fn read_from<R: Read>(mut readable: R) -> Result<InformationElement> {
        let mut information_element: InformationElement = Default::default();
        information_element.id = try!(readable.read_u8());
        information_element.length = try!(readable.read_u16::<BigEndian>());
        let bytes_read = try!(readable.take(information_element.length as u64)
                              .read_to_end(&mut information_element.contents));
        assert!(!(bytes_read > information_element.length as usize));
        if bytes_read < information_element.length as usize {
            return Err(Error::Undersized(bytes_read + 3));
        }
        Ok(information_element)
    }

    /// Returns the length of the information element.
    ///
    /// This is not the same as the internal length, but is rather the length of the contents plus
    /// the length of the IE header.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::io::{Read, Seek, SeekFrom};
    /// # use std::fs::File;
    /// # use sbd::information_element::InformationElement;
    /// # let mut file = File::open("data/0-mo.sbd").unwrap();
    /// # file.seek(SeekFrom::Start(3)).unwrap();
    /// # let readable = file.take(31);
    /// let information_element = InformationElement::read_from(readable).unwrap();
    /// assert_eq!(31, information_element.len());
    /// ```
    pub fn len(&self) -> u16 {
        self.length + 3
    }

    /// Returns the id of the information element.
    pub fn id(&self) -> u8 {
        self.id
    }

    /// Returns a object that can `Read` over the contents of this information element.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::io::{Read, Seek, SeekFrom};
    /// # use std::fs::File;
    /// # use sbd::information_element::InformationElement;
    /// # let mut file = File::open("data/0-mo.sbd").unwrap();
    /// # file.seek(SeekFrom::Start(3)).unwrap();
    /// # let readable = file.take(31);
    /// let information_element = InformationElement::read_from(readable).unwrap();
    /// let mut readable = information_element.as_contents_reader();
    /// let mut buffer: Vec<u8> = Vec::new();
    /// readable.read_to_end(&mut buffer);
    /// ```
    pub fn as_contents_reader<'a>(&self) -> Cursor<&[u8]> {
        Cursor::new(&self.contents[..])
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    use std::io::{Read, Seek, SeekFrom};
    use std::fs::File;

    #[test]
    fn read_from() {
        let mut file = File::open("data/0-mo.sbd").unwrap();
        file.seek(SeekFrom::Start(3)).unwrap();
        let readable = file.take(31);
        InformationElement::read_from(readable).unwrap();
    }

    #[test]
    fn len() {
        let mut file = File::open("data/0-mo.sbd").unwrap();
        file.seek(SeekFrom::Start(3)).unwrap();
        let readable = file.take(31);
        let ie = InformationElement::read_from(readable).unwrap();
        assert_eq!(31, ie.len());
    }

    #[test]
    fn undersized() {
        let mut file = File::open("data/0-mo.sbd").unwrap();
        file.seek(SeekFrom::Start(3)).unwrap();
        let readable = file.take(30);
        assert!(InformationElement::read_from(readable).is_err());
    }
}
<commit_msg>Typo in docs for SessionStatus<commit_after>//! An information element is a portion of a SBD message.
//!
//! Information elements come after the SBD header. They come in many types, including more
//! header-type information and the actual data payload.

use std::io::{Cursor, Read};

use byteorder::{ReadBytesExt, BigEndian};

use {Error, Result};

/// Indicates the success or failure of the SBD session.
enum_from_primitive! {
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum SessionStatus {
    Ok = 0,
    OkMobileTerminatedTooLarge = 1,
    OkLocationUnacceptableQuality = 2,
    Timeout = 10,
    MobileOriginatedTooLarge = 12,
    RFLinkLoss = 13,
    IMEIProtocolAnomaly = 14,
    Prohibited = 15,
    Unknown,
}
}

/// An information element, or IE.
///
/// These are the building blocks of a SBD message. There are several types, generally divided into
/// MO and MT IE's. This general structure just holds the basic IE data, when then can be converted
/// into a specific type of IE.
#[derive(Debug, Default)]
pub struct InformationElement {
    id: u8,
    length: u16,
    contents: Vec<u8>,
}

impl InformationElement {

    /// Reads an information element from something that implements `Read`.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::io::{Read, Seek, SeekFrom};
    /// use std::fs::File;
    /// use sbd::information_element::InformationElement;
    /// let mut file = File::open("data/0-mo.sbd").unwrap();
    /// file.seek(SeekFrom::Start(3)).unwrap();
    /// let readable = file.take(31);
    /// InformationElement::read_from(readable).unwrap();
    /// ```
    pub fn read_from<R: Read>(mut readable: R) -> Result<InformationElement> {
        let mut information_element: InformationElement = Default::default();
        information_element.id = try!(readable.read_u8());
        information_element.length = try!(readable.read_u16::<BigEndian>());
        let bytes_read = try!(readable.take(information_element.length as u64)
                              .read_to_end(&mut information_element.contents));
        assert!(!(bytes_read > information_element.length as usize));
        if bytes_read < information_element.length as usize {
            return Err(Error::Undersized(bytes_read + 3));
        }
        Ok(information_element)
    }

    /// Returns the length of the information element.
    ///
    /// This is not the same as the internal length, but is rather the length of the contents plus
    /// the length of the IE header.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::io::{Read, Seek, SeekFrom};
    /// # use std::fs::File;
    /// # use sbd::information_element::InformationElement;
    /// # let mut file = File::open("data/0-mo.sbd").unwrap();
    /// # file.seek(SeekFrom::Start(3)).unwrap();
    /// # let readable = file.take(31);
    /// let information_element = InformationElement::read_from(readable).unwrap();
    /// assert_eq!(31, information_element.len());
    /// ```
    pub fn len(&self) -> u16 {
        self.length + 3
    }

    /// Returns the id of the information element.
    pub fn id(&self) -> u8 {
        self.id
    }

    /// Returns a object that can `Read` over the contents of this information element.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::io::{Read, Seek, SeekFrom};
    /// # use std::fs::File;
    /// # use sbd::information_element::InformationElement;
    /// # let mut file = File::open("data/0-mo.sbd").unwrap();
    /// # file.seek(SeekFrom::Start(3)).unwrap();
    /// # let readable = file.take(31);
    /// let information_element = InformationElement::read_from(readable).unwrap();
    /// let mut readable = information_element.as_contents_reader();
    /// let mut buffer: Vec<u8> = Vec::new();
    /// readable.read_to_end(&mut buffer);
    /// ```
    pub fn as_contents_reader<'a>(&self) -> Cursor<&[u8]> {
        Cursor::new(&self.contents[..])
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    use std::io::{Read, Seek, SeekFrom};
    use std::fs::File;

    #[test]
    fn read_from() {
        let mut file = File::open("data/0-mo.sbd").unwrap();
        file.seek(SeekFrom::Start(3)).unwrap();
        let readable = file.take(31);
        InformationElement::read_from(readable).unwrap();
    }

    #[test]
    fn len() {
        let mut file = File::open("data/0-mo.sbd").unwrap();
        file.seek(SeekFrom::Start(3)).unwrap();
        let readable = file.take(31);
        let ie = InformationElement::read_from(readable).unwrap();
        assert_eq!(31, ie.len());
    }

    #[test]
    fn undersized() {
        let mut file = File::open("data/0-mo.sbd").unwrap();
        file.seek(SeekFrom::Start(3)).unwrap();
        let readable = file.take(30);
        assert!(InformationElement::read_from(readable).is_err());
    }
}
<|endoftext|>


<commit_before>use sfml::graphics::*;
use sfml::system::{Vector2i, Vector2f};
use sfml::window::Key;
use mousehandler::MousePosHandler;
use resources::Resources;
//use gamewindow::ScrollDir;
use gamewindow::GameWindow;
use gamewindow::ScrollBounds;

const SPEED: f32 = 350.;
const SCROLL_BOUND: f32 = 25.;

pub struct Player<'s> {
    sprite: Sprite<'s>,
}

impl<'s> Player<'s> {
    pub fn new(res: &'s Resources) -> Player<'s> {
        let size = res.img.player.size();

        let mut sprite = Sprite::with_texture(&res.img.player);
        //sprite.set_position2f(size.x as f32 / -2., size.y as f32 / -2.);
        sprite.set_origin2f(size.x as f32 / 2., size.y as f32 / 2.);

        Player {
            sprite,
        }
    }

    /*
    pub fn handle_mouse() {
    }
    */

    pub fn update(&mut self, delta: f32, win: &GameWindow) -> Option<Vector2f> {
        self.handle_keys_realtime(delta, &win.scroll_bounds(SCROLL_BOUND), &win.rwin)
    }

    fn handle_keys_realtime(&mut self, delta: f32, bounds: &ScrollBounds, target: &RenderTarget) -> Option<Vector2f> {
        //let rot = self.sprite.rotation().to_radians();

        if Key::W.is_pressed() {
            //self.sprite.move2f(rot.sin() * SPEED, rot.cos() * -SPEED);
            self.sprite.move2f(0., delta * -SPEED);
        } else if Key::S.is_pressed() {
            //self.sprite.move2f(rot.sin() * -SPEED, rot.cos() * SPEED);
            self.sprite.move2f(0., delta * SPEED);
        }

        if Key::A.is_pressed() {
            //self.sprite.move2f(rot.cos() * -SPEED, rot.sin() * -SPEED);
            self.sprite.move2f(delta * -SPEED, 0.);
        } else if Key::D.is_pressed() {
            //self.sprite.move2f(rot.cos() * SPEED, rot.sin() * SPEED);
            self.sprite.move2f(delta * SPEED, 0.);
        }

        let pixel = target.map_coords_to_pixel_current_view(&self.sprite.position());

        let mut rect = self.sprite.global_bounds();
        rect.left = pixel.x as f32;
        rect.top = pixel.y as f32;

        //println!("{:?}", rect);

        if bounds.left.intersection(&rect).is_some() {
            println!("scroll left");
        } else if bounds.right.intersection(&rect).is_some() {
            println!("scroll right");
        }

        if bounds.top.intersection(&rect).is_some() {
            println!("scroll up");
        } else if bounds.bottom.intersection(&rect).is_some() {
            println!("scroll down");
        }

        None
    }
}

impl<'s> Drawable for Player<'s> {
    fn draw<'se, 'tex, 'sh, 'shte>(
                                   &'se self,
                                   target: &mut RenderTarget,
                                   states: RenderStates<'tex, 'sh, 'shte>)
        where 'se: 'sh
    {
        target.draw_sprite(&self.sprite, states);
    }
}

impl<'s> MousePosHandler for Player<'s> {
    fn mouse_pos(&mut self, target: &RenderTarget, mx: i32, my: i32) {
        let coords = target.map_pixel_to_coords_current_view(
                            &Vector2i::new(mx, my));

        // Player center
        let bounds = self.sprite.global_bounds();
        let cx = bounds.left + bounds.width / 2.;
        let cy = bounds.top + bounds.height / 2.;
        //println!("{} {}", cx, cy);

        // Distance from point to player
        let dx = coords.x - cx;
        let dy = coords.y - cy;
        //println!("{} {}", dx, dy);
        self.sprite.set_rotation(dy.atan2(dx).to_degrees() + 90.);
    }
}
<commit_msg>Make player follow mouse<commit_after>use sfml::graphics::*;
use sfml::system::{Vector2i, Vector2f};
use sfml::window::Key;
use mousehandler::MousePosHandler;
use resources::Resources;
//use gamewindow::ScrollDir;
use gamewindow::GameWindow;
use gamewindow::ScrollBounds;

const SPEED: f32 = 350.;
const SCROLL_BOUND: f32 = 25.;

pub struct Player<'s> {
    sprite: Sprite<'s>,
}

impl<'s> Player<'s> {
    pub fn new(res: &'s Resources) -> Player<'s> {
        let size = res.img.player.size();

        let mut sprite = Sprite::with_texture(&res.img.player);
        //sprite.set_position2f(size.x as f32 / -2., size.y as f32 / -2.);
        sprite.set_origin2f(size.x as f32 / 2., size.y as f32 / 2.);

        Player {
            sprite,
        }
    }

    /*
    pub fn handle_mouse() {
    }
    */

    pub fn update(&mut self, delta: f32, win: &GameWindow) -> Option<Vector2f> {
        self.handle_keys_realtime(delta, &win.scroll_bounds(SCROLL_BOUND), &win.rwin)
    }

    fn handle_keys_realtime(&mut self, delta: f32, bounds: &ScrollBounds, target: &RenderTarget) -> Option<Vector2f> {
        let rot = self.sprite.rotation().to_radians();

        if Key::W.is_pressed() {
            self.sprite.move2f(rot.sin() * delta * SPEED, rot.cos() * delta * -SPEED);
            //self.sprite.move2f(0., delta * -SPEED);
        } else if Key::S.is_pressed() {
            self.sprite.move2f(rot.sin() * delta * -SPEED, rot.cos() * delta * SPEED);
            //self.sprite.move2f(0., delta * SPEED);
        }

        if Key::A.is_pressed() {
            self.sprite.move2f(rot.cos() * delta * -SPEED, rot.sin() * delta * -SPEED);
            //self.sprite.move2f(delta * -SPEED, 0.);
        } else if Key::D.is_pressed() {
            self.sprite.move2f(rot.cos() * delta * SPEED, rot.sin() * delta * SPEED);
            //self.sprite.move2f(delta * SPEED, 0.);
        }

        let pixel = target.map_coords_to_pixel_current_view(&self.sprite.position());

        let mut rect = self.sprite.global_bounds();
        rect.left = pixel.x as f32;
        rect.top = pixel.y as f32;

        //println!("{:?}", rect);

        if bounds.left.intersection(&rect).is_some() {
            println!("scroll left");
        } else if bounds.right.intersection(&rect).is_some() {
            println!("scroll right");
        }

        if bounds.top.intersection(&rect).is_some() {
            println!("scroll up");
        } else if bounds.bottom.intersection(&rect).is_some() {
            println!("scroll down");
        }

        None
    }
}

impl<'s> Drawable for Player<'s> {
    fn draw<'se, 'tex, 'sh, 'shte>(
                                   &'se self,
                                   target: &mut RenderTarget,
                                   states: RenderStates<'tex, 'sh, 'shte>)
        where 'se: 'sh
    {
        target.draw_sprite(&self.sprite, states);
    }
}

impl<'s> MousePosHandler for Player<'s> {
    fn mouse_pos(&mut self, target: &RenderTarget, mx: i32, my: i32) {
        let coords = target.map_pixel_to_coords_current_view(
                            &Vector2i::new(mx, my));

        // Player center
        let bounds = self.sprite.global_bounds();
        let cx = bounds.left + bounds.width / 2.;
        let cy = bounds.top + bounds.height / 2.;
        //println!("{} {}", cx, cy);

        // Distance from point to player
        let dx = coords.x - cx;
        let dy = coords.y - cy;
        //println!("{} {}", dx, dy);
        self.sprite.set_rotation(dy.atan2(dx).to_degrees() + 90.);
    }
}
<|endoftext|>


<commit_before>use syntax::ast::TokenTree;
use syntax::codemap::Span;
use syntax::ptr::P;

use syntax::ast::Expr;
use syntax::ext::base::{ExtCtxt, MacResult, MacEager};
use syntax::parse::parser::Parser;
use syntax::parse::token::Token;

pub fn expand<'cx>(cx: &'cx mut ExtCtxt, _: Span,
               tts: &[TokenTree]) -> Box<MacResult + 'cx> {
    let mut parser = cx.new_parser_from_tts(tts);
    let expr = parse_json(cx, &mut parser);
    if &parser.token != &Token::Eof {
        cx.span_fatal(parser.span, "expected end of `json!` macro invocation");
    }
    MacEager::expr(expr)
}

fn parse_json(cx: &ExtCtxt, parser: &mut Parser) -> P<Expr> {
    use syntax::ext::build::AstBuilder;
    use syntax::parse::token::{DelimToken, IdentStyle};

    macro_rules! comma_sep {
        () =>  {
            ::syntax::parse::common::SeqSep {
                sep: Some(Token::Comma),
                trailing_sep_allowed: true // we could be JSON pedants...
            }
        }
    }

    let orig_span = parser.span;

    match &parser.token {
        &Token::OpenDelim(DelimToken::Bracket) => {
            parser.bump();
            let r_bracket = Token::CloseDelim(DelimToken::Bracket);
            let exprs = parser.parse_seq_to_end(&r_bracket, comma_sep!(), |p| {
                parse_json(cx, p)
            });
            let exprs = cx.expr_vec(orig_span, exprs);
            quote_expr!(cx, {{
                use ::std::boxed::Box;
                let xs: Box<[_]> = Box::new($exprs);
                ::rustc_serialize::json::Json::Array(xs.into_vec())
            }})
        },
        &Token::OpenDelim(DelimToken::Brace) => {
            parser.bump();
            let r_brace = Token::CloseDelim(DelimToken::Brace);
            let kvs = parser.parse_seq_to_end(&r_brace, comma_sep!(), |p| {
                let (istr, _) = p.parse_str();
                let s = &*istr;
                p.expect(&Token::Colon);
                let key = quote_expr!(cx, {{
                    use ::std::borrow::ToOwned;
                    $s.to_owned()
                }});
                (key, parse_json(cx, p))
            });
            let ob = quote_expr!(cx, _ob);
            let mut stmts = vec![];
            for &(ref key, ref value) in kvs.iter() {
                stmts.push(quote_stmt!(cx, $ob.insert($key, $value)));
            }
            quote_expr!(cx, {{
                let mut $ob = ::std::collections::BTreeMap::new();
                $stmts;
                ::rustc_serialize::json::Json::Object($ob)
            }})
        },
        &Token::OpenDelim(DelimToken::Paren) => {
            let expr = parser.parse_expr();
            quote_expr!(cx, {{
                use ::rustc_serialize::json::ToJson;
                ($expr).to_json()
            }})
        },
        &Token::Ident(id, IdentStyle::Plain) if id.as_str() == "null" => {
            parser.bump();
            quote_expr!(cx, { ::rustc_serialize::json::Json::Null })
        },
        _ => { // TODO: investigate can_begin_expr (maybe eliminate need for parens)?
            let expr = parser.parse_literal_maybe_minus();
            quote_expr!(cx, {{
                use ::rustc_serialize::json::ToJson;
                ($expr).to_json()
            }})
        }
    }
}
<commit_msg>Update for rustc 1.0.0-nightly (6b95d8bed 2015-04-09) (built 2015-04-10)<commit_after>use syntax::ast::TokenTree;
use syntax::codemap::Span;
use syntax::ptr::P;

use syntax::ast::Expr;
use syntax::ext::base::{ExtCtxt, MacResult, MacEager};
use syntax::parse::parser::Parser;
use syntax::parse::token::Token;

pub fn expand<'cx>(cx: &'cx mut ExtCtxt, _: Span,
               tts: &[TokenTree]) -> Box<MacResult + 'cx> {
    let mut parser = cx.new_parser_from_tts(tts);
    let expr = parse_json(cx, &mut parser);
    if &parser.token != &Token::Eof {
        cx.span_fatal(parser.span, "expected end of `json!` macro invocation");
    }
    MacEager::expr(expr)
}

fn parse_json(cx: &ExtCtxt, parser: &mut Parser) -> P<Expr> {
    use syntax::ext::build::AstBuilder;
    use syntax::parse::token::{DelimToken, IdentStyle};

    macro_rules! comma_sep {
        () =>  {
            ::syntax::parse::common::SeqSep {
                sep: Some(Token::Comma),
                trailing_sep_allowed: true // we could be JSON pedants...
            }
        }
    }

    let orig_span = parser.span;

    match &parser.token {
        &Token::OpenDelim(DelimToken::Bracket) => {
            let _ = parser.bump();
            let r_bracket = Token::CloseDelim(DelimToken::Bracket);
            let exprs = parser.parse_seq_to_end(&r_bracket, comma_sep!(), |p| {
                Ok(parse_json(cx, p))
            }).ok().unwrap();
            let exprs = cx.expr_vec(orig_span, exprs);
            quote_expr!(cx, {{
                use ::std::boxed::Box;
                let xs: Box<[_]> = Box::new($exprs);
                ::rustc_serialize::json::Json::Array(xs.into_vec())
            }})
        },
        &Token::OpenDelim(DelimToken::Brace) => {
            let _ = parser.bump();
            let r_brace = Token::CloseDelim(DelimToken::Brace);
            let kvs = parser.parse_seq_to_end(&r_brace, comma_sep!(), |p| {
                let (istr, _) = p.parse_str().ok().unwrap();
                let s = &*istr;
                let _ = p.expect(&Token::Colon);
                let key = quote_expr!(cx, {{
                    use ::std::borrow::ToOwned;
                    $s.to_owned()
                }});
                Ok((key, parse_json(cx, p)))
            }).ok().unwrap();
            let ob = quote_expr!(cx, _ob);
            let mut stmts = vec![];
            for &(ref key, ref value) in kvs.iter() {
                stmts.push(quote_stmt!(cx, $ob.insert($key, $value)));
            }
            quote_expr!(cx, {{
                let mut $ob = ::std::collections::BTreeMap::new();
                $stmts;
                ::rustc_serialize::json::Json::Object($ob)
            }})
        },
        &Token::OpenDelim(DelimToken::Paren) => {
            let expr = parser.parse_expr();
            quote_expr!(cx, {{
                use ::rustc_serialize::json::ToJson;
                ($expr).to_json()
            }})
        },
        &Token::Ident(id, IdentStyle::Plain) if id.as_str() == "null" => {
            let _ = parser.bump();
            quote_expr!(cx, { ::rustc_serialize::json::Json::Null })
        },
        _ => { // TODO: investigate can_begin_expr (maybe eliminate need for parens)?
            let expr = parser.parse_literal_maybe_minus().ok().unwrap();
            quote_expr!(cx, {{
                use ::rustc_serialize::json::ToJson;
                ($expr).to_json()
            }})
        }
    }
}
<|endoftext|>


<commit_before>use ast::{Expr, ConstExpr, BlockExpr, TypeOfExpr, LocalExpr, GetConstFieldExpr, GetFieldExpr, CallExpr, WhileLoopExpr, IfExpr, SwitchExpr, ObjectDeclExpr, ArrayDeclExpr, FunctionDeclExpr, ArrowFunctionDeclExpr, UnaryOpExpr, NumOpExpr, BitOpExpr, LogOpExpr, CompOpExpr, ConstructExpr, ReturnExpr, ThrowExpr, AssignExpr};
use ast::{CNum, CInt, CString, CBool, CRegExp, CNull, CUndefined};
use ast::{OpSub, OpAdd, OpMul, OpDiv, OpMod};
use ast::UnaryMinus;
use ast::{BitAnd, BitOr, BitXor, BitShl, BitShr};
use ast::{LogAnd, LogOr};
use ast::{CompEqual, CompNotEqual, CompStrictEqual, CompStrictNotEqual, CompGreaterThan, CompGreaterThanOrEqual, CompLessThan, CompLessThanOrEqual};
use js::value::{Value, ValueData, VNull, VUndefined, VString, VNumber, VInteger, VObject, VBoolean, VFunction, ResultValue, to_value, from_value};
use js::object::{INSTANCE_PROTOTYPE, PROTOTYPE, ObjectData};
use js::function::{RegularFunc, RegularFunction};
use js::{console, math, object, array, function, json, number, error, uri, string};
use collections::treemap::TreeMap;
use std::vec::Vec;
use std::gc::Gc;
use std::cell::RefCell;
/// An execution engine
pub trait Executor {
	/// Makes a new execution engine
	fn new() -> Self;
	/// Sets a global variable
	fn set_global(&mut self, name:StrBuf, val:Value) -> Value;
	/// Gets a global variable
	fn get_global(&self, name:StrBuf) -> Value;
	/// Make a new scope
	fn make_scope(&mut self) -> Gc<RefCell<ObjectData>>;
	/// Destroy the current scope
	fn destroy_scope(&mut self) -> ();
	/// Runs the expression
	fn run(&mut self, expr:&Expr) -> ResultValue;
}
#[deriving(Clone)]
/// An intepreter
pub struct Interpreter {
	/// An object representing the global variables
	global: Value,
	/// The scopes
	scopes: Vec<Gc<RefCell<ObjectData>>>,
}
impl Executor for Interpreter {
	fn new() -> Interpreter {
		let global = ValueData::new_obj(None);
		object::init(global);
		console::init(global);
		math::init(global);
		array::init(global);
		function::init(global);
		json::init(global);
		number::init(global);
		error::init(global);
		number::init(global);
		string::init(global);
		uri::init(global);
		Interpreter {global: global, scopes: Vec::new()}
	}
	fn set_global(&mut self, name:StrBuf, val:Value) -> Value {
		self.global.borrow().set_field(name, val)
	}
	fn get_global(&self, name:StrBuf) -> Value {
		self.global.borrow().get_field(name)
	}
	fn make_scope(&mut self) -> Gc<RefCell<ObjectData>> {
		let value = Gc::new(RefCell::new(TreeMap::new()));
		self.scopes.push(value.clone());
		value
	}
	fn destroy_scope(&mut self) -> () {
		self.scopes.pop();
	}
	fn run(&mut self, expr:&Expr) -> ResultValue {
		match expr.def {
			ConstExpr(CNull) => Ok(Gc::new(VNull)),
			ConstExpr(CUndefined) => Ok(Gc::new(VUndefined)),
			ConstExpr(CNum(num)) => Ok(to_value(num)),
			ConstExpr(CInt(num)) => Ok(to_value(num)),
			ConstExpr(CString(ref str)) => Ok(Gc::new(VString(StrBuf::from_str(str.as_slice())))),
			ConstExpr(CBool(val)) => Ok(Gc::new(VBoolean(val))),
			ConstExpr(CRegExp(_, _, _)) => Ok(Gc::new(VNull)),
			BlockExpr(ref es) => {
				let mut obj = Gc::new(VNull);
				for e in es.iter() {
					let val = try!(self.run(e));
					if e == es.last().unwrap() {
						obj = val;
					}
				}
				Ok(obj)
			},
			LocalExpr(ref name) => {
				let mut value = Gc::new(VUndefined);
				for scope in self.scopes.iter().rev() {
					match scope.borrow().borrow().find(name) {
						Some(v) => {
							value = v.value.clone();
							break;
						}
						None => ()
					}
				}
				Ok(if value.borrow().is_undefined() {
					self.global.borrow().get_field(name.clone())
				} else {
					value
				})
			},
			GetConstFieldExpr(ref obj, ref field) => {
				let val_obj = try!(self.run(*obj));
				Ok(val_obj.borrow().get_field(field.clone()))
			},
			GetFieldExpr(ref obj, ref field) => {
				let val_obj = try!(self.run(*obj));
				let val_field = try!(self.run(*field));
				Ok(val_obj.borrow().get_field(val_field.borrow().to_str()))
			},
			CallExpr(ref callee, ref args) => {
				let (this, func) = match callee.def {
					GetConstFieldExpr(ref obj, ref field) => {
						let obj = try!(self.run(*obj));
						(obj, obj.borrow().get_field(field.clone()))
					},
					GetFieldExpr(ref obj, ref field) => {
						let obj = try!(self.run(*obj));
						let field = try!(self.run(*field));
						(obj, obj.borrow().get_field(field.borrow().to_str()))
					},
					_ => (self.global.clone(), try!(self.run(callee.clone())))
				};
				let mut v_args = Vec::with_capacity(args.len());
				for arg in args.iter() {
					v_args.push(try!(self.run(arg)));
				}
				match *func.borrow() {
					VFunction(ref func) => {
						func.borrow().call(self, this, Gc::new(VNull), v_args)
					},
					_ => Err(Gc::new(VUndefined))
				}
			},
			WhileLoopExpr(ref cond, ref expr) => {
				let mut result = Gc::new(VUndefined);
				while try!(self.run(*cond)).borrow().is_true() {
					result = try!(self.run(*expr));
				}
				Ok(result)
			},
			IfExpr(ref cond, ref expr, None) => {
				Ok(if try!(self.run(*cond)).borrow().is_true() {
					try!(self.run(*expr))
				} else {
					Gc::new(VUndefined)
				})
			},
			IfExpr(ref cond,ref expr, Some(ref else_e)) => {
				Ok(if try!(self.run(*cond)).borrow().is_true() {
					try!(self.run(*expr))
				} else {
					try!(self.run(*else_e))
				})
			},
			SwitchExpr(ref val_e, ref vals, ref default) => {
				let val = try!(self.run(*val_e)).borrow().clone();
				let mut result = Gc::new(VNull);
				let mut matched = false;
				for tup in vals.iter() {
					let tup:&(Expr, Vec<Expr>) = tup;
					match *tup {
						(ref cond, ref block) if(val == *try!(self.run(cond)).borrow()) => {
							matched = true;
							let last_expr = block.last().unwrap();
							for expr in block.iter() {
								let e_result = try!(self.run(expr));
								if expr == last_expr {
									result = e_result;
								}
							}
						},
						_ => ()
					}
				}
				if !matched && default.is_some() {
					result = try!(self.run(*default.as_ref().unwrap()));
				}
				Ok(result)
			},
			ObjectDeclExpr(ref map) => {
				let obj = ValueData::new_obj(Some(self.global));
				for (key, val) in map.iter() {
					obj.borrow().set_field(key.clone(), try!(self.run(val)));
				}
				Ok(obj)
			},
			ArrayDeclExpr(ref arr) => {
				let arr_map = ValueData::new_obj(Some(self.global));
				let mut index : i32 = 0;
				for val in arr.iter() {
					let val = try!(self.run(val));
					arr_map.borrow().set_field(index.to_str(), val);
					index += 1;
				}
				arr_map.borrow().set_field_slice(INSTANCE_PROTOTYPE, self.get_global("Array".into_strbuf()).borrow().get_field_slice(PROTOTYPE));
				arr_map.borrow().set_field_slice("length", to_value(index));
				Ok(arr_map)
			},
			FunctionDeclExpr(ref name, ref args, ref expr) => {
				let function = RegularFunc(RegularFunction::new(*expr.clone(), args.clone()));
				let val = Gc::new(VFunction(RefCell::new(function)));
				if name.is_some() {
					self.global.borrow().set_field(name.clone().unwrap(), val);
				}
				Ok(val)
			},
			ArrowFunctionDeclExpr(ref args, ref expr) => {
				let function = RegularFunc(RegularFunction::new(*expr.clone(), args.clone()));
				Ok(Gc::new(VFunction(RefCell::new(function))))
			},
			NumOpExpr(ref op, ref a, ref b) => {
				let v_r_a = try!(self.run(*a));
				let v_r_b = try!(self.run(*b));
				let v_a = v_r_a.borrow();
				let v_b = v_r_b.borrow();
				Ok(Gc::new(match *op {
					OpAdd => *v_a + *v_b,
					OpSub => *v_a - *v_b,
					OpMul => *v_a * *v_b,
					OpDiv => *v_a / *v_b,
					OpMod => *v_a % *v_b
				}))
			},
			UnaryOpExpr(ref op, ref a) => {
				let v_r_a = try!(self.run(*a));
				let v_a = v_r_a.borrow();
				Ok(match *op {
					UnaryMinus => to_value(-v_a.to_num()),
					_ => to_value(-1i32)
				})
			},
			BitOpExpr(ref op, ref a, ref b) => {
				let v_r_a = try!(self.run(*a));
				let v_r_b = try!(self.run(*b));
				let v_a = v_r_a.borrow();
				let v_b = v_r_b.borrow();
				Ok(Gc::new(match *op {
					BitAnd => *v_a & *v_b,
					BitOr => *v_a | *v_b,
					BitXor => *v_a ^ *v_b,
					BitShl => *v_a << *v_b,
					BitShr => *v_a >> *v_b
				}))
			},
			CompOpExpr(ref op, ref a, ref b) => {
				let v_r_a = try!(self.run(*a));
				let v_r_b = try!(self.run(*b));
				let v_a = v_r_a.borrow();
				let v_b = v_r_b.borrow();
				Ok(to_value(match *op {
					CompEqual if v_a.is_object() => v_r_a.ptr_eq(&v_r_b),
					CompEqual => v_a == v_b,
					CompNotEqual if v_a.is_object() => !v_r_a.ptr_eq(&v_r_b),
					CompNotEqual => v_a != v_b,
					CompStrictEqual if v_a.is_object() => v_r_a.ptr_eq(&v_r_b),
					CompStrictEqual => v_a == v_b,
					CompStrictNotEqual if v_a.is_object() => !v_r_a.ptr_eq(&v_r_b),
					CompStrictNotEqual => v_a != v_b,
					CompGreaterThan => v_a.to_num() > v_b.to_num(),
					CompGreaterThanOrEqual => v_a.to_num() >= v_b.to_num(),
					CompLessThan => v_a.to_num() < v_b.to_num(),
					CompLessThanOrEqual => v_a.to_num() <= v_b.to_num()
				}))
			},
			LogOpExpr(ref op, ref a, ref b) => {
				let v_a = from_value::<bool>(try!(self.run(*a))).unwrap();
				let v_b = from_value::<bool>(try!(self.run(*b))).unwrap();
				Ok(match *op {
					LogAnd => to_value(v_a && v_b),
					LogOr => to_value(v_a || v_b)
				})
			},
			ConstructExpr(ref callee, ref args) => {
				let func = try!(self.run(*callee));
				let mut v_args = Vec::with_capacity(args.len());
				for arg in args.iter() {
					v_args.push(try!(self.run(arg)));
				}
				let this = Gc::new(VObject(RefCell::new(TreeMap::new())));
				this.borrow().set_field_slice(INSTANCE_PROTOTYPE, func.borrow().get_field_slice(PROTOTYPE));
				Ok(match *func.borrow() {
					VFunction(ref func) => {
						try!(func.borrow().call(self, this, Gc::new(VNull), v_args));
						this
					},
					_ => Gc::new(VUndefined)
				})
			},
			ReturnExpr(ref ret) => {
				match *ret {
					Some(ref v) =>
						self.run(*v),
					None => Ok(Gc::new(VUndefined))
				}
			},
			ThrowExpr(ref ex) => Err(try!(self.run(*ex))),
			AssignExpr(ref ref_e, ref val_e) => {
				let val = try!(self.run(*val_e));
				match ref_e.def {
					LocalExpr(ref name) => {
						self.global.borrow().set_field(name.clone(), val);
					},
					GetConstFieldExpr(ref obj, ref field) => {
						let val_obj = try!(self.run(*obj));
						val_obj.borrow().set_field(field.clone(), val);
					},
					_ => ()
				}
				Ok(val)
			},
			TypeOfExpr(ref val_e) => {
				let val = try!(self.run(*val_e));
				Ok(to_value(match *val.borrow() {
					VUndefined => "undefined",
					VNull | VObject(_) => "object",
					VBoolean(_) => "boolean",
					VNumber(_) | VInteger(_) => "number",
					VString(_) => "string",
					VFunction(_) => "function"
				}))
			}
		}
	}
}<commit_msg>Remove duplicate in executor initialisor<commit_after>use ast::{Expr, ConstExpr, BlockExpr, TypeOfExpr, LocalExpr, GetConstFieldExpr, GetFieldExpr, CallExpr, WhileLoopExpr, IfExpr, SwitchExpr, ObjectDeclExpr, ArrayDeclExpr, FunctionDeclExpr, ArrowFunctionDeclExpr, UnaryOpExpr, NumOpExpr, BitOpExpr, LogOpExpr, CompOpExpr, ConstructExpr, ReturnExpr, ThrowExpr, AssignExpr};
use ast::{CNum, CInt, CString, CBool, CRegExp, CNull, CUndefined};
use ast::{OpSub, OpAdd, OpMul, OpDiv, OpMod};
use ast::UnaryMinus;
use ast::{BitAnd, BitOr, BitXor, BitShl, BitShr};
use ast::{LogAnd, LogOr};
use ast::{CompEqual, CompNotEqual, CompStrictEqual, CompStrictNotEqual, CompGreaterThan, CompGreaterThanOrEqual, CompLessThan, CompLessThanOrEqual};
use js::value::{Value, ValueData, VNull, VUndefined, VString, VNumber, VInteger, VObject, VBoolean, VFunction, ResultValue, to_value, from_value};
use js::object::{INSTANCE_PROTOTYPE, PROTOTYPE, ObjectData};
use js::function::{RegularFunc, RegularFunction};
use js::{console, math, object, array, function, json, number, error, uri, string};
use collections::treemap::TreeMap;
use std::vec::Vec;
use std::gc::Gc;
use std::cell::RefCell;
/// An execution engine
pub trait Executor {
	/// Makes a new execution engine
	fn new() -> Self;
	/// Sets a global variable
	fn set_global(&mut self, name:StrBuf, val:Value) -> Value;
	/// Gets a global variable
	fn get_global(&self, name:StrBuf) -> Value;
	/// Make a new scope
	fn make_scope(&mut self) -> Gc<RefCell<ObjectData>>;
	/// Destroy the current scope
	fn destroy_scope(&mut self) -> ();
	/// Runs the expression
	fn run(&mut self, expr:&Expr) -> ResultValue;
}
#[deriving(Clone)]
/// An intepreter
pub struct Interpreter {
	/// An object representing the global variables
	global: Value,
	/// The scopes
	scopes: Vec<Gc<RefCell<ObjectData>>>,
}
impl Executor for Interpreter {
	fn new() -> Interpreter {
		let global = ValueData::new_obj(None);
		object::init(global);
		console::init(global);
		math::init(global);
		array::init(global);
		function::init(global);
		json::init(global);
		number::init(global);
		error::init(global);
		string::init(global);
		uri::init(global);
		Interpreter {global: global, scopes: Vec::new()}
	}
	fn set_global(&mut self, name:StrBuf, val:Value) -> Value {
		self.global.borrow().set_field(name, val)
	}
	fn get_global(&self, name:StrBuf) -> Value {
		self.global.borrow().get_field(name)
	}
	fn make_scope(&mut self) -> Gc<RefCell<ObjectData>> {
		let value = Gc::new(RefCell::new(TreeMap::new()));
		self.scopes.push(value.clone());
		value
	}
	fn destroy_scope(&mut self) -> () {
		self.scopes.pop();
	}
	fn run(&mut self, expr:&Expr) -> ResultValue {
		match expr.def {
			ConstExpr(CNull) => Ok(Gc::new(VNull)),
			ConstExpr(CUndefined) => Ok(Gc::new(VUndefined)),
			ConstExpr(CNum(num)) => Ok(to_value(num)),
			ConstExpr(CInt(num)) => Ok(to_value(num)),
			ConstExpr(CString(ref str)) => Ok(Gc::new(VString(StrBuf::from_str(str.as_slice())))),
			ConstExpr(CBool(val)) => Ok(Gc::new(VBoolean(val))),
			ConstExpr(CRegExp(_, _, _)) => Ok(Gc::new(VNull)),
			BlockExpr(ref es) => {
				let mut obj = Gc::new(VNull);
				for e in es.iter() {
					let val = try!(self.run(e));
					if e == es.last().unwrap() {
						obj = val;
					}
				}
				Ok(obj)
			},
			LocalExpr(ref name) => {
				let mut value = Gc::new(VUndefined);
				for scope in self.scopes.iter().rev() {
					match scope.borrow().borrow().find(name) {
						Some(v) => {
							value = v.value.clone();
							break;
						}
						None => ()
					}
				}
				Ok(if value.borrow().is_undefined() {
					self.global.borrow().get_field(name.clone())
				} else {
					value
				})
			},
			GetConstFieldExpr(ref obj, ref field) => {
				let val_obj = try!(self.run(*obj));
				Ok(val_obj.borrow().get_field(field.clone()))
			},
			GetFieldExpr(ref obj, ref field) => {
				let val_obj = try!(self.run(*obj));
				let val_field = try!(self.run(*field));
				Ok(val_obj.borrow().get_field(val_field.borrow().to_str()))
			},
			CallExpr(ref callee, ref args) => {
				let (this, func) = match callee.def {
					GetConstFieldExpr(ref obj, ref field) => {
						let obj = try!(self.run(*obj));
						(obj, obj.borrow().get_field(field.clone()))
					},
					GetFieldExpr(ref obj, ref field) => {
						let obj = try!(self.run(*obj));
						let field = try!(self.run(*field));
						(obj, obj.borrow().get_field(field.borrow().to_str()))
					},
					_ => (self.global.clone(), try!(self.run(callee.clone())))
				};
				let mut v_args = Vec::with_capacity(args.len());
				for arg in args.iter() {
					v_args.push(try!(self.run(arg)));
				}
				match *func.borrow() {
					VFunction(ref func) => {
						func.borrow().call(self, this, Gc::new(VNull), v_args)
					},
					_ => Err(Gc::new(VUndefined))
				}
			},
			WhileLoopExpr(ref cond, ref expr) => {
				let mut result = Gc::new(VUndefined);
				while try!(self.run(*cond)).borrow().is_true() {
					result = try!(self.run(*expr));
				}
				Ok(result)
			},
			IfExpr(ref cond, ref expr, None) => {
				Ok(if try!(self.run(*cond)).borrow().is_true() {
					try!(self.run(*expr))
				} else {
					Gc::new(VUndefined)
				})
			},
			IfExpr(ref cond,ref expr, Some(ref else_e)) => {
				Ok(if try!(self.run(*cond)).borrow().is_true() {
					try!(self.run(*expr))
				} else {
					try!(self.run(*else_e))
				})
			},
			SwitchExpr(ref val_e, ref vals, ref default) => {
				let val = try!(self.run(*val_e)).borrow().clone();
				let mut result = Gc::new(VNull);
				let mut matched = false;
				for tup in vals.iter() {
					let tup:&(Expr, Vec<Expr>) = tup;
					match *tup {
						(ref cond, ref block) if(val == *try!(self.run(cond)).borrow()) => {
							matched = true;
							let last_expr = block.last().unwrap();
							for expr in block.iter() {
								let e_result = try!(self.run(expr));
								if expr == last_expr {
									result = e_result;
								}
							}
						},
						_ => ()
					}
				}
				if !matched && default.is_some() {
					result = try!(self.run(*default.as_ref().unwrap()));
				}
				Ok(result)
			},
			ObjectDeclExpr(ref map) => {
				let obj = ValueData::new_obj(Some(self.global));
				for (key, val) in map.iter() {
					obj.borrow().set_field(key.clone(), try!(self.run(val)));
				}
				Ok(obj)
			},
			ArrayDeclExpr(ref arr) => {
				let arr_map = ValueData::new_obj(Some(self.global));
				let mut index : i32 = 0;
				for val in arr.iter() {
					let val = try!(self.run(val));
					arr_map.borrow().set_field(index.to_str(), val);
					index += 1;
				}
				arr_map.borrow().set_field_slice(INSTANCE_PROTOTYPE, self.get_global("Array".into_strbuf()).borrow().get_field_slice(PROTOTYPE));
				arr_map.borrow().set_field_slice("length", to_value(index));
				Ok(arr_map)
			},
			FunctionDeclExpr(ref name, ref args, ref expr) => {
				let function = RegularFunc(RegularFunction::new(*expr.clone(), args.clone()));
				let val = Gc::new(VFunction(RefCell::new(function)));
				if name.is_some() {
					self.global.borrow().set_field(name.clone().unwrap(), val);
				}
				Ok(val)
			},
			ArrowFunctionDeclExpr(ref args, ref expr) => {
				let function = RegularFunc(RegularFunction::new(*expr.clone(), args.clone()));
				Ok(Gc::new(VFunction(RefCell::new(function))))
			},
			NumOpExpr(ref op, ref a, ref b) => {
				let v_r_a = try!(self.run(*a));
				let v_r_b = try!(self.run(*b));
				let v_a = v_r_a.borrow();
				let v_b = v_r_b.borrow();
				Ok(Gc::new(match *op {
					OpAdd => *v_a + *v_b,
					OpSub => *v_a - *v_b,
					OpMul => *v_a * *v_b,
					OpDiv => *v_a / *v_b,
					OpMod => *v_a % *v_b
				}))
			},
			UnaryOpExpr(ref op, ref a) => {
				let v_r_a = try!(self.run(*a));
				let v_a = v_r_a.borrow();
				Ok(match *op {
					UnaryMinus => to_value(-v_a.to_num()),
					_ => to_value(-1i32)
				})
			},
			BitOpExpr(ref op, ref a, ref b) => {
				let v_r_a = try!(self.run(*a));
				let v_r_b = try!(self.run(*b));
				let v_a = v_r_a.borrow();
				let v_b = v_r_b.borrow();
				Ok(Gc::new(match *op {
					BitAnd => *v_a & *v_b,
					BitOr => *v_a | *v_b,
					BitXor => *v_a ^ *v_b,
					BitShl => *v_a << *v_b,
					BitShr => *v_a >> *v_b
				}))
			},
			CompOpExpr(ref op, ref a, ref b) => {
				let v_r_a = try!(self.run(*a));
				let v_r_b = try!(self.run(*b));
				let v_a = v_r_a.borrow();
				let v_b = v_r_b.borrow();
				Ok(to_value(match *op {
					CompEqual if v_a.is_object() => v_r_a.ptr_eq(&v_r_b),
					CompEqual => v_a == v_b,
					CompNotEqual if v_a.is_object() => !v_r_a.ptr_eq(&v_r_b),
					CompNotEqual => v_a != v_b,
					CompStrictEqual if v_a.is_object() => v_r_a.ptr_eq(&v_r_b),
					CompStrictEqual => v_a == v_b,
					CompStrictNotEqual if v_a.is_object() => !v_r_a.ptr_eq(&v_r_b),
					CompStrictNotEqual => v_a != v_b,
					CompGreaterThan => v_a.to_num() > v_b.to_num(),
					CompGreaterThanOrEqual => v_a.to_num() >= v_b.to_num(),
					CompLessThan => v_a.to_num() < v_b.to_num(),
					CompLessThanOrEqual => v_a.to_num() <= v_b.to_num()
				}))
			},
			LogOpExpr(ref op, ref a, ref b) => {
				let v_a = from_value::<bool>(try!(self.run(*a))).unwrap();
				let v_b = from_value::<bool>(try!(self.run(*b))).unwrap();
				Ok(match *op {
					LogAnd => to_value(v_a && v_b),
					LogOr => to_value(v_a || v_b)
				})
			},
			ConstructExpr(ref callee, ref args) => {
				let func = try!(self.run(*callee));
				let mut v_args = Vec::with_capacity(args.len());
				for arg in args.iter() {
					v_args.push(try!(self.run(arg)));
				}
				let this = Gc::new(VObject(RefCell::new(TreeMap::new())));
				this.borrow().set_field_slice(INSTANCE_PROTOTYPE, func.borrow().get_field_slice(PROTOTYPE));
				Ok(match *func.borrow() {
					VFunction(ref func) => {
						try!(func.borrow().call(self, this, Gc::new(VNull), v_args));
						this
					},
					_ => Gc::new(VUndefined)
				})
			},
			ReturnExpr(ref ret) => {
				match *ret {
					Some(ref v) =>
						self.run(*v),
					None => Ok(Gc::new(VUndefined))
				}
			},
			ThrowExpr(ref ex) => Err(try!(self.run(*ex))),
			AssignExpr(ref ref_e, ref val_e) => {
				let val = try!(self.run(*val_e));
				match ref_e.def {
					LocalExpr(ref name) => {
						self.global.borrow().set_field(name.clone(), val);
					},
					GetConstFieldExpr(ref obj, ref field) => {
						let val_obj = try!(self.run(*obj));
						val_obj.borrow().set_field(field.clone(), val);
					},
					_ => ()
				}
				Ok(val)
			},
			TypeOfExpr(ref val_e) => {
				let val = try!(self.run(*val_e));
				Ok(to_value(match *val.borrow() {
					VUndefined => "undefined",
					VNull | VObject(_) => "object",
					VBoolean(_) => "boolean",
					VNumber(_) | VInteger(_) => "number",
					VString(_) => "string",
					VFunction(_) => "function"
				}))
			}
		}
	}
}<|endoftext|>


<commit_before>use std::cmp::{PartialOrd, Ordering};
use std::iter::repeat;
use std::usize;

use frame::Frame;
use draw::RGB;

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct Point {
   pub x: i64,
   pub y: i64,
}

impl Point {
   #[inline]
   pub fn new(x: i64, y: i64) -> Self {
      Point {
         x: x,
         y: y,
      }
   }
}

impl Default for Point {
   fn default() -> Point {
      Point::new(0, 0)
   }
}

impl PartialOrd for Point {
   fn partial_cmp(&self, other: &Point) -> Option<Ordering> {
      Some(self.cmp(other))
   }
}

impl Ord for Point {
   fn cmp(&self, other: &Point) -> Ordering {
      if self.y < other.y {
         Ordering::Less
      } else if self.y > other.y {
         Ordering::Greater
      } else if self.x < other.x {
         Ordering::Less
      } else if self.x > other.x {
         Ordering::Greater
      } else {
         Ordering::Equal
      }
   }
}

#[derive(Debug, Clone, Copy)]
pub struct Segment {
   pub p1: usize,
   pub p2: usize,
}

impl Segment {
   #[inline]
   pub fn new(p1: usize, p2: usize) -> Self {
      Segment {
         p1: p1,
         p2: p2,
      }
   }
}

impl Default for Segment {
   fn default() -> Segment {
      Segment::new(0, 0)
   }
}

#[derive(Debug, Clone, Copy)]
pub struct Circle {
   pub center: usize,
   pub radius: i64,
}

impl Circle {
   #[inline]
   pub fn new(center: usize, radius: i64) -> Self {
      Circle {
         center: center,
         radius: radius,
      }
   }
}

impl Default for Circle {
   fn default() -> Circle {
      Circle::new(0, 0)
   }
}

#[derive(Debug, Clone, Copy)]
pub enum EdgeType {
   LTR,  // line top-right
   LTL,  // line top-left
   LBR,  // line bottom-right
   LBL,  // line bottom-left

   LHR,  // line horizontal-right
   LHL,  // line horizontal-left
   LVT,  // line vertical-top
   LVB,  // line vertical-bottom

   CTR, // clockwise arc top-right
   CTL, // clockwise arc top-left
   CBR, // clockwise arc bottom-right
   CBL, // clockwise arc bottom-left

   ATR, // anti-clockwise arc top-right
   ATL, // anti-clockwise arc top-left
   ABR, // anti-clockwise arc bottom-right
   ABL, // anti-clockwise arc bottom-left
}

impl EdgeType {
   #[inline]
   pub fn reversed(&self) -> bool {
      match *self {
         EdgeType::LBR | EdgeType::LBL | EdgeType::LHL | EdgeType::LVB |
         EdgeType::CBR | EdgeType::CBL | EdgeType::ATR | EdgeType::ATL => {
            true
         },
         _ => {
            false
         }
      }
   }
}

#[derive(Debug, Clone, Copy)]
pub struct Edge {
   pub edge_type: EdgeType,
   pub segment: usize,
   pub circle: usize,
}

impl Edge {
   #[inline]
   pub fn new(edge_type: EdgeType, segment: usize, circle: usize) -> Self {
      Edge {
         edge_type: edge_type,
         segment: segment,
         circle: circle,
      }
   }

   #[inline]
   pub fn reversed(&self) -> bool {
      self.edge_type.reversed()
   }
}

impl Default for Edge {
   fn default() -> Edge {
      Edge::new(EdgeType::LTR, 0, 0)
   }
}

#[derive(Debug, Clone)]
pub struct Poly {
   pub start: usize,
   pub end: usize,
   pub color: usize,
}

impl Poly {
   #[inline]
   pub fn new(start: usize, end: usize, color: usize) -> Self {
      Poly {
         start: start,
         end: end,
         color: color,
      }
   }
}

impl Default for Poly {
   fn default() -> Poly {
      Poly::new(0, 0, 0)
   }
}

pub struct Scene {
   pub points: Vec<Point>,
   pub segments: Vec<Segment>,
   pub circles: Vec<Circle>,
   pub edges: Vec<Edge>,
   pub polys: Vec<Poly>,
   pub colors: Vec<RGB>,
}

#[derive(Debug, Clone)]
pub struct PolyRef {
   pub start: usize,
   pub end: usize,
   pub src: usize,
}

impl PolyRef {
   #[inline]
   pub fn new(start: usize, end: usize, src: usize) -> Self {
      PolyRef {
         start: start,
         end: end,
         src: src,
      }
   }
}

impl Default for PolyRef {
   fn default() -> PolyRef {
      PolyRef::new(0, 0, 0)
   }
}

pub struct Rasterizer {
   pub points: Vec<Point>,
   pub segments: Vec<Segment>,
   pub edges: Vec<Edge>,
   pub polys: Vec<PolyRef>,

   pub points_end: usize,
   pub segments_end: usize,
   pub edges_end: usize,
   pub polys_end: usize,
}

impl Rasterizer {
   pub fn new() -> Self {
      let points = create_default_vec(65536);
      let segments = create_default_vec(65536);
      let edges = create_default_vec(65536);
      let polys = create_default_vec(65536);

      Rasterizer {
         points: points,
         segments: segments,
         edges: edges,
         polys: polys,

         points_end: 0,
         segments_end: 0,
         edges_end: 0,
         polys_end: 0,
      }
   }

   #[allow(unused_variables)]
   pub fn render(&mut self, scene: &Scene, frame: &mut Frame) {
      self.tranfer_scene(scene);

      self.check_correctness(scene);
   }

   pub fn tranfer_scene(&mut self, scene: &Scene) {
      self.points_end = scene.points.len();
      for i in 0..self.points_end {
         self.points[i] = scene.points[i];
      }

      self.segments_end = scene.segments.len();
      for i in 0..self.segments_end {
         self.segments[i] = scene.segments[i];
      }

      self.edges_end = scene.edges.len();
      for i in 0..self.edges_end {
         self.edges[i] = scene.edges[i];
      }

      self.polys_end = scene.polys.len();
      for i in 0..self.polys_end {
         self.polys[i].start = scene.polys[i].start;
         self.polys[i].end = scene.polys[i].end;
         self.polys[i].src = i;
      }
   }

   pub fn check_correctness(&self, scene: &Scene) {
      for poly in &self.polys[0..self.polys_end] {
         self.check_poly_connected(poly);
         self.check_segments_orientation(poly);
         self.check_edges_orientation(poly);
      }

      self.check_index_coverage(scene);
   }

   fn check_poly_connected(&self, poly: &PolyRef) {
      let mut prev = self.edge_head(&self.edges[poly.end - 1]);

      for edge_index in poly.start..poly.end {
         let ref edge = self.edges[edge_index];

         let current = self.edge_tail(edge);
         if current != prev {
            panic!("Unclosed poly : {:?}", poly);
         }

         prev = self.edge_head(edge);
      }
   }

   fn check_segments_orientation(&self, poly: &PolyRef) {
      for edge_index in poly.start..poly.end {
         let ref edge = self.edges[edge_index];
         let ref segment = self.segments[edge.segment];

         let ref less = self.points[segment.p1];
         let ref greater = self.points[segment.p2];

         if greater <= less {
            panic!("Wrong segment orientation : {:?} / {:?}", edge, segment);
         }
      }
   }

   fn check_edges_orientation(&self, poly: &PolyRef) {
      for edge_index in poly.start..poly.end {
         let ref edge = self.edges[edge_index];

         let tail = self.edge_tail(edge);
         let head = self.edge_head(edge);

         let reversed = edge.reversed();

         if (reversed && tail <= head) || (!reversed && head <= tail) {
            panic!("Wrong edge orientation : {:?}", edge);
         }
      }
   }

   fn check_index_coverage(&self, scene: &Scene) {
      self.check_edge_index_coverage();
      self.check_circle_index_coverage(scene);
      self.check_segment_index_coverage();
      self.check_point_index_coverage(scene);
   }

   fn check_edge_index_coverage(&self) {
      let len = self.edges_end;
      let mut coverage: Vec<bool> = repeat(false).take(len).collect();

      for poly in &self.polys[0..self.polys_end] {
         for edge_index in poly.start..poly.end {
            coverage[edge_index] = true;
         }
      }

      if coverage.contains(&false) {
         panic!("Unreferenced edge found");
      }
   }

   fn check_circle_index_coverage(&self, scene: &Scene) {
      let len = scene.circles.len();
      let mut coverage: Vec<bool> = repeat(false).take(len).collect();

      for edge in &self.edges[0..self.edges_end] {
         if edge.circle != usize::MAX {
            coverage[edge.circle] = true;
         }
      }

      if coverage.contains(&false) {
         panic!("Unreferenced circle found");
      }
   }

   fn check_segment_index_coverage(&self) {
      let len = self.segments_end;
      let mut coverage: Vec<bool> = repeat(false).take(len).collect();

      for edge in &self.edges[0..self.edges_end] {
         coverage[edge.segment] = true;
      }

      if coverage.contains(&false) {
         panic!("Unreferenced segment found");
      }
   }

   fn check_point_index_coverage(&self, scene: &Scene) {
      let len = self.points_end;
      let mut coverage: Vec<bool> = repeat(false).take(len).collect();

      for circle in &scene.circles {
         coverage[circle.center] = true;
      }

      for segment in &self.segments[0..self.segments_end] {
         coverage[segment.p1] = true;
         coverage[segment.p2] = true;
      }

      if coverage.contains(&false) {
         panic!("Unreferenced segment found");
      }
   }

   // TODO: Combine into edge_head_tail method?

   fn edge_head(&self, edge: &Edge) -> &Point {
      let ref segment = self.segments[edge.segment];
      if edge.reversed() {
         &self.points[segment.p1]
      } else {
         &self.points[segment.p2]
      }
   }

   fn edge_tail(&self, edge: &Edge) -> &Point {
      let ref segment = self.segments[edge.segment];
      if edge.reversed() {
         &self.points[segment.p2]
      } else {
         &self.points[segment.p1]
      }
   }
}

pub fn create_default_vec<T>(capacity: usize) -> Vec<T> where T: Default + Clone {
   repeat(T::default()).take(capacity).collect()
}

<commit_msg>Intersection structs definition<commit_after>use std::cmp::{PartialOrd, Ordering};
use std::iter::repeat;
use std::usize;

use frame::Frame;
use draw::RGB;

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct Point {
   pub x: i64,
   pub y: i64,
}

impl Point {
   #[inline]
   pub fn new(x: i64, y: i64) -> Self {
      Point {
         x: x,
         y: y,
      }
   }
}

impl Default for Point {
   fn default() -> Point {
      Point::new(0, 0)
   }
}

impl PartialOrd for Point {
   fn partial_cmp(&self, other: &Point) -> Option<Ordering> {
      Some(self.cmp(other))
   }
}

impl Ord for Point {
   fn cmp(&self, other: &Point) -> Ordering {
      if self.y < other.y {
         Ordering::Less
      } else if self.y > other.y {
         Ordering::Greater
      } else if self.x < other.x {
         Ordering::Less
      } else if self.x > other.x {
         Ordering::Greater
      } else {
         Ordering::Equal
      }
   }
}

#[derive(Debug, Clone, Copy)]
pub struct Segment {
   pub p1: usize,
   pub p2: usize,
}

impl Segment {
   #[inline]
   pub fn new(p1: usize, p2: usize) -> Self {
      Segment {
         p1: p1,
         p2: p2,
      }
   }
}

impl Default for Segment {
   fn default() -> Segment {
      Segment::new(0, 0)
   }
}

#[derive(Debug, Clone, Copy)]
pub struct Circle {
   pub center: usize,
   pub radius: i64,
}

impl Circle {
   #[inline]
   pub fn new(center: usize, radius: i64) -> Self {
      Circle {
         center: center,
         radius: radius,
      }
   }
}

impl Default for Circle {
   fn default() -> Circle {
      Circle::new(0, 0)
   }
}

#[derive(Debug, Clone, Copy)]
pub enum EdgeType {
   LTR,  // line top-right
   LTL,  // line top-left
   LBR,  // line bottom-right
   LBL,  // line bottom-left

   LHR,  // line horizontal-right
   LHL,  // line horizontal-left
   LVT,  // line vertical-top
   LVB,  // line vertical-bottom

   CTR, // clockwise arc top-right
   CTL, // clockwise arc top-left
   CBR, // clockwise arc bottom-right
   CBL, // clockwise arc bottom-left

   ATR, // anti-clockwise arc top-right
   ATL, // anti-clockwise arc top-left
   ABR, // anti-clockwise arc bottom-right
   ABL, // anti-clockwise arc bottom-left
}

impl EdgeType {
   #[inline]
   pub fn reversed(&self) -> bool {
      match *self {
         EdgeType::LBR | EdgeType::LBL | EdgeType::LHL | EdgeType::LVB |
         EdgeType::CBR | EdgeType::CBL | EdgeType::ATR | EdgeType::ATL => {
            true
         },
         _ => {
            false
         }
      }
   }
}

#[derive(Debug, Clone, Copy)]
pub struct Edge {
   pub edge_type: EdgeType,
   pub segment: usize,
   pub circle: usize,
}

impl Edge {
   #[inline]
   pub fn new(edge_type: EdgeType, segment: usize, circle: usize) -> Self {
      Edge {
         edge_type: edge_type,
         segment: segment,
         circle: circle,
      }
   }

   #[inline]
   pub fn reversed(&self) -> bool {
      self.edge_type.reversed()
   }
}

impl Default for Edge {
   fn default() -> Edge {
      Edge::new(EdgeType::LTR, 0, 0)
   }
}

#[derive(Debug, Clone)]
pub struct Poly {
   pub start: usize,
   pub end: usize,
   pub color: usize,
}

impl Poly {
   #[inline]
   pub fn new(start: usize, end: usize, color: usize) -> Self {
      Poly {
         start: start,
         end: end,
         color: color,
      }
   }
}

impl Default for Poly {
   fn default() -> Poly {
      Poly::new(0, 0, 0)
   }
}

pub struct Scene {
   pub points: Vec<Point>,
   pub segments: Vec<Segment>,
   pub circles: Vec<Circle>,
   pub edges: Vec<Edge>,
   pub polys: Vec<Poly>,
   pub colors: Vec<RGB>,
}

#[derive(Debug, Clone)]
pub struct PolyRef {
   pub start: usize,
   pub end: usize,
   pub src: usize,
}

impl PolyRef {
   #[inline]
   pub fn new(start: usize, end: usize, src: usize) -> Self {
      PolyRef {
         start: start,
         end: end,
         src: src,
      }
   }
}

impl Default for PolyRef {
   fn default() -> PolyRef {
      PolyRef::new(0, 0, 0)
   }
}

#[derive(Debug, Clone)]
pub struct IntersectionRef {
   first_px: i64,
   start: usize,
   end: usize,
}

impl IntersectionRef {
   #[inline]
   pub fn new(first_px: i64, start: usize, end: usize) -> Self {
      IntersectionRef {
         first_px: first_px,
         start: start,
         end: end,
      }
   }
}

impl Default for IntersectionRef {
   #[inline]
   fn default() -> IntersectionRef {
      IntersectionRef::new(0, 0, 0)
   }
}

pub struct Rasterizer {
   pub points: Vec<Point>,
   pub segments: Vec<Segment>,
   pub edges: Vec<Edge>,
   pub polys: Vec<PolyRef>,

   pub points_end: usize,
   pub segments_end: usize,
   pub edges_end: usize,
   pub polys_end: usize,

   pub vert_intersections_ref: Vec<IntersectionRef>,
   pub hori_intersections_ref: Vec<IntersectionRef>,
   pub vert_intersections: Vec<i64>,
   pub hori_intersections: Vec<i64>,
}

impl Rasterizer {
   pub fn new() -> Self {
      let points = create_default_vec(65536);
      let segments = create_default_vec(65536);
      let edges = create_default_vec(65536);
      let polys = create_default_vec(65536);

      let vert_intersections_ref = create_default_vec(65536);
      let hori_intersections_ref = create_default_vec(65536);
      let vert_intersections = create_default_vec(65536);
      let hori_intersections = create_default_vec(65536);

      Rasterizer {
         points: points,
         segments: segments,
         edges: edges,
         polys: polys,

         points_end: 0,
         segments_end: 0,
         edges_end: 0,
         polys_end: 0,

         vert_intersections_ref: vert_intersections_ref,
         hori_intersections_ref: hori_intersections_ref,
         vert_intersections: vert_intersections,
         hori_intersections: hori_intersections,
      }
   }

   #[allow(unused_variables)]
   pub fn render(&mut self, scene: &Scene, frame: &mut Frame) {
      self.tranfer_scene(scene);

      self.check_correctness(scene);
   }

   pub fn tranfer_scene(&mut self, scene: &Scene) {
      self.points_end = scene.points.len();
      for i in 0..self.points_end {
         self.points[i] = scene.points[i];
      }

      self.segments_end = scene.segments.len();
      for i in 0..self.segments_end {
         self.segments[i] = scene.segments[i];
      }

      self.edges_end = scene.edges.len();
      for i in 0..self.edges_end {
         self.edges[i] = scene.edges[i];
      }

      self.polys_end = scene.polys.len();
      for i in 0..self.polys_end {
         self.polys[i].start = scene.polys[i].start;
         self.polys[i].end = scene.polys[i].end;
         self.polys[i].src = i;
      }
   }

   pub fn check_correctness(&self, scene: &Scene) {
      for poly in &self.polys[0..self.polys_end] {
         self.check_poly_connected(poly);
         self.check_segments_orientation(poly);
         self.check_edges_orientation(poly);
      }

      self.check_index_coverage(scene);
   }

   fn check_poly_connected(&self, poly: &PolyRef) {
      let mut prev = self.edge_head(&self.edges[poly.end - 1]);

      for edge_index in poly.start..poly.end {
         let ref edge = self.edges[edge_index];

         let current = self.edge_tail(edge);
         if current != prev {
            panic!("Unclosed poly : {:?}", poly);
         }

         prev = self.edge_head(edge);
      }
   }

   fn check_segments_orientation(&self, poly: &PolyRef) {
      for edge_index in poly.start..poly.end {
         let ref edge = self.edges[edge_index];
         let ref segment = self.segments[edge.segment];

         let ref less = self.points[segment.p1];
         let ref greater = self.points[segment.p2];

         if greater <= less {
            panic!("Wrong segment orientation : {:?} / {:?}", edge, segment);
         }
      }
   }

   fn check_edges_orientation(&self, poly: &PolyRef) {
      for edge_index in poly.start..poly.end {
         let ref edge = self.edges[edge_index];

         let tail = self.edge_tail(edge);
         let head = self.edge_head(edge);

         let reversed = edge.reversed();

         if (reversed && tail <= head) || (!reversed && head <= tail) {
            panic!("Wrong edge orientation : {:?}", edge);
         }
      }
   }

   fn check_index_coverage(&self, scene: &Scene) {
      self.check_edge_index_coverage();
      self.check_circle_index_coverage(scene);
      self.check_segment_index_coverage();
      self.check_point_index_coverage(scene);
   }

   fn check_edge_index_coverage(&self) {
      let len = self.edges_end;
      let mut coverage: Vec<bool> = repeat(false).take(len).collect();

      for poly in &self.polys[0..self.polys_end] {
         for edge_index in poly.start..poly.end {
            coverage[edge_index] = true;
         }
      }

      if coverage.contains(&false) {
         panic!("Unreferenced edge found");
      }
   }

   fn check_circle_index_coverage(&self, scene: &Scene) {
      let len = scene.circles.len();
      let mut coverage: Vec<bool> = repeat(false).take(len).collect();

      for edge in &self.edges[0..self.edges_end] {
         if edge.circle != usize::MAX {
            coverage[edge.circle] = true;
         }
      }

      if coverage.contains(&false) {
         panic!("Unreferenced circle found");
      }
   }

   fn check_segment_index_coverage(&self) {
      let len = self.segments_end;
      let mut coverage: Vec<bool> = repeat(false).take(len).collect();

      for edge in &self.edges[0..self.edges_end] {
         coverage[edge.segment] = true;
      }

      if coverage.contains(&false) {
         panic!("Unreferenced segment found");
      }
   }

   fn check_point_index_coverage(&self, scene: &Scene) {
      let len = self.points_end;
      let mut coverage: Vec<bool> = repeat(false).take(len).collect();

      for circle in &scene.circles {
         coverage[circle.center] = true;
      }

      for segment in &self.segments[0..self.segments_end] {
         coverage[segment.p1] = true;
         coverage[segment.p2] = true;
      }

      if coverage.contains(&false) {
         panic!("Unreferenced segment found");
      }
   }

   // TODO: Combine into edge_head_tail method?

   fn edge_head(&self, edge: &Edge) -> &Point {
      let ref segment = self.segments[edge.segment];
      if edge.reversed() {
         &self.points[segment.p1]
      } else {
         &self.points[segment.p2]
      }
   }

   fn edge_tail(&self, edge: &Edge) -> &Point {
      let ref segment = self.segments[edge.segment];
      if edge.reversed() {
         &self.points[segment.p2]
      } else {
         &self.points[segment.p1]
      }
   }
}

pub fn create_default_vec<T>(capacity: usize) -> Vec<T> where T: Default + Clone {
   repeat(T::default()).take(capacity).collect()
}

<|endoftext|>