parser: revision 1 done; super dirty

This commit is contained in:
2017-05-24 15:19:03 -04:00
parent 67b9c8c525
commit 3ea766724c
2 changed files with 87 additions and 9 deletions

20
examples/factorial Normal file
View File

@@ -0,0 +1,20 @@
ENTRY 22
LOAD -3
CONST 2
LT
BRF 10
CONST 1
RET
LOAD -3
LOAD -3
CONST 1
SUB
CALL 0 1
MULT
RET
CONST 12
CALL 0 1
IPRINT
CONST 10
PRINT
HALT

View File

@@ -2,14 +2,45 @@ use std::fs::File;
use std::io; use std::io;
use std::io::Read; use std::io::Read;
use std::env; use std::env;
use std::collections::HashMap;
const EXEC: [(i32, (&'static str, i32)); 1] = [ const EXEC_RPR: [(&'static str, i32); 28] = [
(0, ("add", 0)) ("entry", 1),
("add", 0),
("sub", 0),
("mult", 0),
("div", 0),
("mod", 0),
("lt", 0),
("eq", 0),
("gt", 0),
("br", 1),
("brt", 1),
("brf", 1),
("const", 1),
("load", 1),
("gload", 1),
("store", 1),
("gstore", 1),
("print", 0),
("pop", 0),
("halt", 0),
("leq", 0),
("geq", 0),
("call", 2),
("ret", 0),
("iprint", 0),
("fetch", 0),
("inc", 0),
("dec", 0)
]; ];
struct Exec { fn build_opcodes() -> HashMap<&'static str, (i64, i32)> {
arguments: i32, let mut opcodes = HashMap::new();
name: String for (i, elem) in EXEC_RPR.iter().enumerate() {
opcodes.insert((*elem).0, (i as i64, (*elem).1));
}
return opcodes;
} }
fn usage(pname: String) { fn usage(pname: String) {
@@ -23,14 +54,41 @@ fn get_contents(fname: String) -> Result<String, io::Error> {
Ok(contents) Ok(contents)
} }
fn parse(contents: String) -> Vec<Exec> { fn parse(contents: String, opcodes: HashMap<&'static str, (i64, i32)>) -> Vec<i64> {
return vec![]; let mut code = Vec::new();
for line in contents.split("\n") {
if line.is_empty() { continue }
let tmp = line.split(" ").map(String::from).collect::<Vec<String>>();
let (op, args) = tmp.split_first().expect("malformatted line!");
let opcode: &str = &op.to_lowercase()[..];
match opcodes.get(opcode) {
Some(v) => {
code.push(v.0);
if args.len() as i32 != v.1 {
panic!("Expected {} arguments for opcode {}, but got {}!", v.1, opcode, args.len());
}
for elem in args {
match elem.parse::<i64>() {
Ok(v) => code.push(v),
_ => panic!("Could not parse argument {} to instruction {} as number!", elem, opcode)
}
}
}
None => panic!("Do not know opcode {}!", opcode)
}
}
return code
} }
fn exec(instructions: Vec<Exec>) { fn exec(instructions: Vec<i64>) {
for elem in instructions {
println!("{}", elem);
}
} }
fn main() { fn main() {
let opcodes = build_opcodes();
let args: Vec<_> = env::args().collect(); let args: Vec<_> = env::args().collect();
if args.len() != 2 { if args.len() != 2 {
@@ -49,7 +107,7 @@ fn main() {
} }
}; };
let parsed = parse(contents); let parsed = parse(contents, opcodes);
let execd = exec(parsed); let execd = exec(parsed);
} }