Skip to content

Instantly share code, notes, and snippets.

@chikoski
Created September 7, 2013 06:45
Show Gist options
  • Save chikoski/6473388 to your computer and use it in GitHub Desktop.
Save chikoski/6473388 to your computer and use it in GitHub Desktop.
extern mod std;
use std::os;
pub mod kankore{
extern mod std;
use std::io;
use std::path;
use std::result;
use std::str;
enum Token{
PTR_INCREMENT,
PTR_DECREMENT,
VALUE_INCREMENT,
VALUE_DECREMENT,
PUTCHAR,
GETCHAR,
BEGIN_WHILE,
END_WHILE,
NIL
}
struct Interpreter{
pc: uint,
program: ~[Token],
ptr: uint,
memory: ~[uint]
}
impl Interpreter{
fn increment_pc(&mut self){
let new_ptr = self.pc + 1;
self.pc = if(new_ptr <= self.program.len()){
new_ptr
}else{
self.program.len()
}
}
fn decrement_pc(&mut self){
let new_ptr = self.pc - 1;
self.pc = if(new_ptr < 0){
0
}else{
new_ptr
}
}
fn increment_ptr(&mut self){
let new_ptr = self.ptr + 1;
self.ptr = if(new_ptr <= self.memory.len()){
new_ptr
}else{
self.memory.len()
}
}
fn decrement_ptr(&mut self){
let new_ptr = self.ptr - 1;
self.ptr = if(new_ptr < 0){
0
}else{
new_ptr
}
}
fn increment_value(&mut self){
self.memory[self.ptr] = self.memory[self.ptr] + 1
}
fn decrement_value(&mut self){
let new_val = self.memory[self.ptr] + 1;
self.memory[self.ptr] = if(new_val < 0){
0
}else{
new_val
}
}
fn putchar(&self){
print(fmt!("%s", str::from_byte(self.memory[self.ptr] as u8)));
}
fn getchar(&mut self){
}
fn test_ptr_value(&self)->bool{
self.memory[self.ptr] == 0
}
fn find_close_blacket(&self)->uint{
let mut index = self.pc;
let mut depth = 0;
while(index < self.program.len()){
let token = self.program[index];
match(token){
BEGIN_WHILE => depth = depth + 1,
END_WHILE => {
if(depth > 0){
depth = depth - 1;
}else{
break;
}
},
_ => {}
}
index = index + 1;
}
return index
}
fn find_open_blacket(&self)->uint{
let mut index = self.pc;
let mut depth = 0;
while(0 < index){
let token = self.program[index];
match(token){
END_WHILE => depth = depth + 1,
BEGIN_WHILE => {
if(depth > 0){
depth = depth - 1;
}else{
break;
}
},
_ => {}
}
index = index - 1;
}
return index;
}
fn begin_while(&mut self){
if(self.test_ptr_value()){
self.increment_pc();
}else{
self.pc = self.find_close_blacket();
println(fmt!("begin: %?", self.pc));
}
}
fn end_while(&mut self){
if(self.test_ptr_value()){
self.increment_pc();
}else{
self.pc = self.find_open_blacket();
}
}
fn nop(&mut self){
}
fn one_step_eval(&mut self){
let token = self.program[self.pc];
match(token){
PTR_INCREMENT => {
self.increment_ptr();
self.increment_pc();
},
PTR_DECREMENT => {
self.decrement_ptr();
self.increment_pc();
},
VALUE_INCREMENT => {
self.increment_value();
self.increment_pc();
},
VALUE_DECREMENT => {
self.decrement_value();
self.increment_pc();
},
PUTCHAR => {
self.putchar();
self.increment_pc();
},
GETCHAR => {
self.getchar();
self.increment_pc();
}
BEGIN_WHILE => {
self.begin_while();
}
END_WHILE => {
self.end_while();
}
_ => {
self.nop();
self.increment_pc();
}
};
}
pub fn eval(&mut self){
while(self.pc < self.program.len()){
self.one_step_eval();
}
}
}
pub fn new_interpreter(tokens:~[Token]) -> Interpreter{
Interpreter{
pc: 0,
ptr: 0,
memory: ~[0, ..128],
program: tokens
}
}
pub fn parse(lines:~[~str]) -> ~[Token]{
lines.map(|line|
match(line){
&~"撃ちます!Fire!" => PTR_INCREMENT,
&~"あぁあっ!" => PTR_DECREMENT,
&~"Burning...Love!"| &~"英国で産まれた帰国子女の金剛デース!ヨロシクオネガイシマース!" | &~"紅茶が飲みたいネー" | &~"Hi!今日も良い天気ネー!" => VALUE_INCREMENT,
&~"提督ー!" | &~"Shit!提督に貰った大切な装備ガッ!" => VALUE_DECREMENT,
&~"全砲門!Fire!" | &~"私の活躍見てくれたの?もっと頑張るから目を離しちゃNo!なんだからネ!" => PUTCHAR,
&~"Yes!私の実力、見せてあげるネー" => GETCHAR,
&~"私たちの出番ネ!Follow me!皆さん、着いて来て下さいネー" => BEGIN_WHILE,
&~"戦果Resultがあがったヨー!" => END_WHILE,
_ => NIL
})
}
pub fn lex(filename:~str)-> ~[~str]{
let file = path::PosixPath(filename);
let result = io::file_reader(&file);
let mut buf: ~[~str] = ~[];
if(result::is_ok(&result)){
let reader = result.unwrap();
loop{
let line = reader.read_line();
if(reader.eof()){
break
}
buf.push(line);
}
}
return buf;
}
}
fn main(){
let arguments = os::args();
if(arguments.len() > 1){
let tokens = kankore::parse(kankore::lex(arguments[1]));
let mut interpreter = kankore::new_interpreter(tokens);
interpreter.eval();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment