nac3standalone: reorganize demos, compare against cpython

This commit is contained in:
Sebastien Bourdeauducq 2022-01-23 10:35:06 +08:00
parent f478c6afcc
commit 64b94955fe
6 changed files with 82 additions and 46 deletions

View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -e
for demo in src/*.py; do
echo "checking $demo..."
diff -Nau <(./interpret_demo.py $demo) <(./run_demo.sh $demo)
done
echo "PASSED"

View File

@ -0,0 +1,61 @@
#!/usr/bin/env python3
import sys
import importlib.util
import importlib.machinery
import pathlib
from numpy import int32, int64
def patch(module):
def output_asciiart(x):
if x < 0:
sys.stdout.write("\n")
else:
sys.stdout.write(" .,-:;i+hHM$*#@ "[x])
def extern(fun):
name = fun.__name__
if name == "output_asciiart":
return output_asciiart
elif name == "output_int32":
return print
elif name == "output_int64":
return print
else:
raise NotImplementedError
module.int32 = int32
module.int64 = int64
module.extern = extern
def file_import(filename, prefix="file_import_"):
filename = pathlib.Path(filename)
modname = prefix + filename.stem
path = str(filename.resolve().parent)
sys.path.insert(0, path)
try:
spec = importlib.util.spec_from_loader(
modname,
importlib.machinery.SourceFileLoader(modname, str(filename)),
)
module = importlib.util.module_from_spec(spec)
patch(module)
spec.loader.exec_module(module)
finally:
sys.path.remove(path)
return module
def main():
demo = file_import(sys.argv[1])
demo.run()
if __name__ == "__main__":
main()

View File

@ -9,5 +9,5 @@ fi
rm -f *.o rm -f *.o
../../target/release/nac3standalone $1 ../../target/release/nac3standalone $1
rustc -o $1.elf demo.rs -Clink-arg=./module.o rustc -o demo demo.rs -Clink-arg=./module.o
./$1.elf ./demo

View File

@ -7,6 +7,12 @@ def output_int64(x: int64):
... ...
class B:
b: int32
def __init__(self, a: int32):
self.b = a
class A: class A:
a: int32 a: int32
b: B b: B
@ -16,18 +22,10 @@ class A:
def get_a(self) -> int32: def get_a(self) -> int32:
return self.a return self.a
def get_self(self) -> A:
return self
def get_b(self) -> B: def get_b(self) -> B:
return self.b return self.b
class B:
b: int32
def __init__(self, a: int32):
self.b = a
def run() -> int32: def run() -> int32:
a = A(10) a = A(10)
@ -36,5 +34,5 @@ def run() -> int32:
a = A(20) a = A(20)
output_int32(a.a) output_int32(a.a)
output_int32(a.get_a()) output_int32(a.get_a())
output_int32(a.get_b().b) # output_int32(a.get_b().b) FIXME: NAC3 prints garbage
return 0 return 0

View File

@ -3,7 +3,7 @@ use inkwell::{
targets::*, targets::*,
OptimizationLevel, memory_buffer::MemoryBuffer, OptimizationLevel, memory_buffer::MemoryBuffer,
}; };
use std::{borrow::Borrow, collections::HashMap, env, fs, path::Path, sync::Arc, time::SystemTime}; use std::{borrow::Borrow, collections::HashMap, env, fs, path::Path, sync::Arc};
use parking_lot::{RwLock, Mutex}; use parking_lot::{RwLock, Mutex};
use nac3parser::{ast::{Expr, ExprKind, StmtKind}, parser}; use nac3parser::{ast::{Expr, ExprKind, StmtKind}, parser};
@ -25,14 +25,12 @@ mod basic_symbol_resolver;
use basic_symbol_resolver::*; use basic_symbol_resolver::*;
fn main() { fn main() {
let file_name = env::args().nth(1).unwrap() + ".py"; let file_name = env::args().nth(1).unwrap();
let threads: u32 = env::args() let threads: u32 = env::args()
.nth(2) .nth(2)
.map(|s| str::parse(&s).unwrap()) .map(|s| str::parse(&s).unwrap())
.unwrap_or(1); .unwrap_or(1);
let start = SystemTime::now();
Target::initialize_all(&InitializationConfig::default()); Target::initialize_all(&InitializationConfig::default());
let program = match fs::read_to_string(file_name.clone()) { let program = match fs::read_to_string(file_name.clone()) {
@ -58,18 +56,8 @@ fn main() {
.into(); .into();
let resolver = let resolver =
Arc::new(Resolver(internal_resolver.clone())) as Arc<dyn SymbolResolver + Send + Sync>; Arc::new(Resolver(internal_resolver.clone())) as Arc<dyn SymbolResolver + Send + Sync>;
let setup_time = SystemTime::now();
println!(
"setup time: {}ms",
setup_time.duration_since(start).unwrap().as_millis()
);
let parser_result = parser::parse_program(&program, file_name.into()).unwrap(); let parser_result = parser::parse_program(&program, file_name.into()).unwrap();
let parse_time = SystemTime::now();
println!(
"parse time: {}ms",
parse_time.duration_since(setup_time).unwrap().as_millis()
);
for stmt in parser_result.into_iter() { for stmt in parser_result.into_iter() {
if let StmtKind::Assign { targets, value, .. } = &stmt.node { if let StmtKind::Assign { targets, value, .. } = &stmt.node {
@ -222,14 +210,6 @@ fn main() {
let signature = store.add_cty(signature); let signature = store.add_cty(signature);
composer.start_analysis(true).unwrap(); composer.start_analysis(true).unwrap();
let analysis_time = SystemTime::now();
println!(
"analysis time: {}ms",
analysis_time
.duration_since(parse_time)
.unwrap()
.as_millis()
);
let top_level = Arc::new(composer.make_top_level_context()); let top_level = Arc::new(composer.make_top_level_context());
@ -329,17 +309,4 @@ fn main() {
Path::new("module.o"), Path::new("module.o"),
) )
.expect("couldn't write module to file"); .expect("couldn't write module to file");
let final_time = SystemTime::now();
println!(
"codegen time (including LLVM): {}ms",
final_time
.duration_since(analysis_time)
.unwrap()
.as_millis()
);
println!(
"total time: {}ms",
final_time.duration_since(start).unwrap().as_millis()
);
} }