소스 검색

adding options

Nicolas Winkler 4 년 전
부모
커밋
707d289d6c
6개의 변경된 파일129개의 추가작업 그리고 23개의 파일을 삭제
  1. 0 1
      Cargo.lock
  2. 0 1
      Cargo.toml
  3. 22 1
      src/compile.rs
  4. 30 10
      src/main.rs
  5. 58 0
      src/options.rs
  6. 19 10
      src/trans/c.rs

+ 0 - 1
Cargo.lock

@@ -231,5 +231,4 @@ dependencies = [
  "dynasm",
  "dynasmrt",
  "typed-arena",
- "winapi",
 ]

+ 0 - 1
Cargo.toml

@@ -11,6 +11,5 @@ edition = "2018"
 [dependencies]
 dynasm = "1.0.1"
 dynasmrt = "1.0.1"
-winapi = "*"
 typed-arena = "1.4.1"
 clap = "2.33.3"

+ 22 - 1
src/compile.rs

@@ -3,6 +3,12 @@ use super::{ir, optimize};
 use std::io::{Write, Read};
 use std::mem;
 use super::ir::{ConstVisitor, Instruction};
+//use mmap::{MemoryMap, MapOption};
+
+/*#[cfg(target_os = "windows")]
+use kernel32::VirtualAlloc;
+#[cfg(target_os = "windows")]
+use winapi::um::winnt::{MEM_COMMIT, PAGE_EXECUTE_READWRITE};*/
 
 use dynasmrt::{DynasmApi, DynasmLabelApi};
 
@@ -76,7 +82,22 @@ impl CodeGenerator {
     pub fn get_callable(self) -> *const u8 {
         let data = self.buffer.finalize().unwrap().to_vec();
         println!("asm buffer of size {}", data.len());
-        let ex = unsafe { VirtualAlloc(0 as _, data.len(), MEM_COMMIT, PAGE_EXECUTE_READWRITE) };
+        //let ex = unsafe { VirtualAlloc(0 as _, data.len(), MEM_COMMIT, PAGE_EXECUTE_READWRITE) };
+        let ex = unsafe {
+            MemoryMap::new(
+                data.len(),
+                &[
+                    MapOption::MapAddr(0 as *mut u8),
+                    MapOption::MapOffset(0),
+                    MapOption::MapFd(-1),
+                    MapOption::MapReadable,
+                    MapOption::MapWritable,
+                    MapOption::MapExecutable,
+                    MapOption::MapNonStandardFlags(libc::MAP_ANON),
+                    MapOption::MapNonStandardFlags(libc::MAP_PRIVATE),
+                ]
+            )
+        };
         unsafe {
             std::ptr::copy_nonoverlapping(data.as_ptr(), ex as _, data.len());
         }

+ 30 - 10
src/main.rs

@@ -4,13 +4,16 @@
 #[macro_use]
 extern crate dynasm;
 
-extern crate winapi;
+//extern crate winapi;
 extern crate typed_arena;
 
 use std::io::{self, Read};
 use std::fs::File;
 use clap::{Arg, App};
+use std::str::FromStr;
+use std::process::exit;
 
+pub mod options;
 pub mod ir;
 pub mod parser;
 pub mod interpret;
@@ -29,17 +32,21 @@ fn main() -> io::Result<()> {
         .author("Nicolas Winkler <nicolas.winkler@gmx.ch>")
         .about("Brainfuck interpreter and transpiler")
         .arg(Arg::with_name("input")
-                 .index(1)
-                 .takes_value(true)
-                 .help("Input file"))
+                .takes_value(true)
+                .help("Input file"))
         .arg(Arg::with_name("transpile")
-                 .long("transpile")
-                 .short("t")
-                 .takes_value(true)
-                 .help("Transpile to language"))
+                .long("transpile")
+                .short("t")
+                .takes_value(true)
+                .help("Transpile to language"))
+        .arg(Arg::with_name("cell size")
+                .long("cell-size")
+                .short("c")
+                .takes_value(true)
+                .help("defines the cell size used"))
         .get_matches();
+    
     let mut buffer = String::new();
-
     if let Some(input) = matches.value_of("input") {
         File::open(&input)?.read_to_string(&mut buffer)?;
     }
@@ -47,6 +54,18 @@ fn main() -> io::Result<()> {
         io::stdin().read_to_string(&mut buffer)?;
     }
 
+    let mut options = options::Options::default();
+
+    if let Some(cell_size) = matches.value_of("cell size") {
+        match options::CellSize::from_str(cell_size) {
+            Ok(cs) => options.cell_size = cs,
+            Err(e) => {
+                eprintln!("invalid cell size '{}'", cell_size);
+                exit(1);
+            }
+        }
+    }
+
     let insts = parser::parse(&buffer);
     if let Ok(mut insts) = insts {
         let mut lin_loop_optimizer = optimize::LinOptimizer::new();
@@ -67,7 +86,7 @@ fn main() -> io::Result<()> {
                 //let dfg = optimize::create_dfg(&mut insts, &arena);
                 let code = if lang == "c" {
                     //trans::c::transpile_dfg(&dfg)
-                    trans::c::transpile(&insts)
+                    trans::c::transpile(&options, &insts)
                 } else if lang == "java" {
                     trans::java::transpile(&insts)
                 } else if lang == "python" {
@@ -75,6 +94,7 @@ fn main() -> io::Result<()> {
                 } else if lang == "zombie_ir" {
                     trans::zombie_ir::transpile(&insts)
                 } else {
+                    eprintln!("invalid transpiler lang '{}'", lang);
                     "".to_owned()
                 };
                 println!("{}", code);

+ 58 - 0
src/options.rs

@@ -0,0 +1,58 @@
+use std::str::FromStr;
+
+pub enum CellLayout {
+    Trusting,
+    Wrapping
+}
+
+
+pub enum CellSize {
+    Int8,
+    Int16,
+    Int32,
+    Int
+}
+
+
+pub struct Options {
+    pub cell_layout: CellLayout,
+    pub memory_size: i64,
+    pub cell_size: CellSize,
+}
+
+
+impl Default for Options {
+    fn default() -> Self {
+        Options {
+            cell_layout: CellLayout::Trusting,
+            memory_size: 0x10000,
+            cell_size: CellSize::Int8,
+        }
+    }
+}
+
+impl FromStr for CellLayout {
+    type Err = &'static str;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        match s {
+            "trusting" => Ok(CellLayout::Trusting),
+            "wrapping" => Ok(CellLayout::Wrapping),
+            _ => Err("invalid cell layout"),
+        }
+    }
+}
+
+impl FromStr for CellSize {
+    type Err = &'static str;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        match s {
+            "8" => Ok(CellSize::Int8),
+            "16" => Ok(CellSize::Int16),
+            "32" => Ok(CellSize::Int32),
+            "int" => Ok(CellSize::Int),
+            _ => Err("invalid cell size"),
+        }
+    }
+}

+ 19 - 10
src/trans/c.rs

@@ -1,10 +1,11 @@
 
-use super::super::{ir, formatter, optimize};
+use super::super::{ir, formatter, optimize, options};
 
 use ir::Instruction;
 use ir::ConstVisitor;
 use formatter::Formatter;
 use optimize::{DfInstr, DfgNode};
+use options::*;
 
 struct CTranspiler {
     pub code_buf: Formatter
@@ -93,29 +94,37 @@ fn generate_dfg(cfg: &Vec<DfInstr>, formatter: &mut Formatter) {
 }
 
 
-pub fn transpile(instrs: &Vec<ir::Instruction>) -> String {
-    let mut transpiler = CTranspiler::default();
+pub fn transpile(opts: &Options, instrs: &Vec<ir::Instruction>) -> String {
+    let mut transpiler = CTranspiler::create(opts);
     transpiler.visit_instructions(instrs);
     transpiler.finalize();
     return transpiler.code_buf.get_code();
 }
 
 
-impl Default for CTranspiler {
-    fn default() -> Self {
+impl CTranspiler {
+    fn create(opts: &Options) -> Self {
         let mut transpiler = CTranspiler{ code_buf: Formatter::new() };
 
-        transpiler.code_buf.add_line(r#"#include <stdio.h>
+        let cell_type = match opts.cell_size {
+            CellSize::Int8 => "uint8_t",
+            CellSize::Int16 => "uint16_t",
+            CellSize::Int32 => "uint32_t",
+            CellSize::Int => "uint64_t"
+        };
+
+
+        transpiler.code_buf.add_line(&format!(r#"#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <inttypes.h>
 
 #define OFF(X) ((uint16_t)(ptr + (uint16_t) (X)))
 
-int main() {
-    uint8_t* mem = (uint8_t*) malloc(0x10000 * sizeof(uint8_t));
-    memset(mem, 0, 0x10000 * sizeof(uint8_t));
-    uint16_t ptr = 0;"#);
+int main() {{
+    {ct}* mem = ({ct}*) malloc(0x10000 * sizeof({ct}));
+    memset(mem, 0, 0x10000 * sizeof({ct}));
+    uint16_t ptr = 0;"#, ct = cell_type));
         transpiler.code_buf.indent();
         transpiler
     }