parser: revision 1 done; super dirty
This commit is contained in:
20
examples/factorial
Normal file
20
examples/factorial
Normal 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
|
76
src/main.rs
76
src/main.rs
@@ -2,14 +2,45 @@ use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::Read;
|
||||
use std::env;
|
||||
use std::collections::HashMap;
|
||||
|
||||
const EXEC: [(i32, (&'static str, i32)); 1] = [
|
||||
(0, ("add", 0))
|
||||
const EXEC_RPR: [(&'static str, i32); 28] = [
|
||||
("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 {
|
||||
arguments: i32,
|
||||
name: String
|
||||
fn build_opcodes() -> HashMap<&'static str, (i64, i32)> {
|
||||
let mut opcodes = HashMap::new();
|
||||
for (i, elem) in EXEC_RPR.iter().enumerate() {
|
||||
opcodes.insert((*elem).0, (i as i64, (*elem).1));
|
||||
}
|
||||
return opcodes;
|
||||
}
|
||||
|
||||
fn usage(pname: String) {
|
||||
@@ -23,14 +54,41 @@ fn get_contents(fname: String) -> Result<String, io::Error> {
|
||||
Ok(contents)
|
||||
}
|
||||
|
||||
fn parse(contents: String) -> Vec<Exec> {
|
||||
return vec![];
|
||||
fn parse(contents: String, opcodes: HashMap<&'static str, (i64, i32)>) -> Vec<i64> {
|
||||
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() {
|
||||
let opcodes = build_opcodes();
|
||||
|
||||
let args: Vec<_> = env::args().collect();
|
||||
|
||||
if args.len() != 2 {
|
||||
@@ -49,7 +107,7 @@ fn main() {
|
||||
}
|
||||
};
|
||||
|
||||
let parsed = parse(contents);
|
||||
let parsed = parse(contents, opcodes);
|
||||
|
||||
let execd = exec(parsed);
|
||||
}
|
||||
|
Reference in New Issue
Block a user