Skip to content

Python AST to CodeVR Scene Converter #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Jul 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4f3d91a
started converting .py files to AST
lborg019 May 24, 2017
dac6798
rust ast client added
lborg019 May 30, 2017
72140d1
rust client communicates with python server
lborg019 May 31, 2017
3ffb496
implemented nonblocking rust client, python server has errors
lborg019 May 31, 2017
433bf07
rust client communicates with python server successfully
lborg019 May 31, 2017
335e734
python server must parse and check file path information given by client
lborg019 May 31, 2017
bfd7275
buffered tcp receive on client side
lborg019 Jun 2, 2017
d97ad97
server and client working. fix output bug on client side (response ge…
lborg019 Jun 4, 2017
25787e4
echop rust client / python server works with strings of any size
lborg019 Jun 4, 2017
987b661
bug fixes for rust client and python server, both working perfect
lborg019 Jun 5, 2017
f179a9d
server calls astexport and writes ast to .json
lborg019 Jun 5, 2017
d452d56
python server sends back the ast of specified .py file to rust client
lborg019 Jun 5, 2017
28339ab
client writes ast in local json file
lborg019 Jun 5, 2017
d82022a
cleaning up files
lborg019 Jun 5, 2017
0f6394d
Merge branch 'master' of github.com:OpenHID/code-vr into feature/pyth…
lborg019 Jun 5, 2017
734d0b0
cleaning up unused lines of code and cargo.toml
lborg019 Jun 5, 2017
68579cd
removing subprocess call
lborg019 Jun 7, 2017
2ea2b5e
split path on client side to create correct .json filename (instead o…
lborg019 Jun 7, 2017
337e47a
client writes file name correctly now
lborg019 Jun 14, 2017
77f53aa
ignoring client/server compiled and residual files
lborg019 Jun 14, 2017
19b7a00
added tests for reading the json file
lborg019 Jun 16, 2017
fea9c10
parser starting to work with serde
lborg019 Jun 20, 2017
75f3416
correctly parsing arbitraty json. beef it up until completion
lborg019 Jun 22, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,5 @@ rusti.sh
Cargo.lock
.cargotarget
/**/*.rs.bk
/languages/client/*.json
/languages/python/*.pyc
10 changes: 10 additions & 0 deletions languages/client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "codevr-python"
version = "0.1.0"
authors = ["lborg019 <[email protected]>"]

[dependencies]
encoding = "0.2"
serde = "1.0.8"
serde_derive = "1.0.8"
serde_json = "1.0.2"
1 change: 1 addition & 0 deletions languages/client/rls.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
unstable_features = true
53 changes: 53 additions & 0 deletions languages/client/src/ast/notworking/function.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
extern crate serde;
extern crate serde_json;

use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
use serde_json::from_str;

#[derive(Serialize, Deserialize, Debug)]
pub struct PyFunction {
name: String
/*lineno: u32,
ast_type: String,
args: u32,*/
}

#[cfg(test)]
mod test {

use ast::function::PyFunction;
use serde_json::from_str;

fn distance(a: (f32, f32), b: (f32, f32)) -> f32 {
((b.0 - a.0).powi(2) + (b.1 - a.1).powi(2)).sqrt()
}

#[test]
fn distance_test() {
assert!(distance((0f32, 0f32), (1f32, 1f32)) == (2f32).sqrt());
}

fn read_code_from_file<P: AsRef<Path>>(path: P) -> Result<PyFunction, Box<Error>>
{
// Open the file in read-only mode.
let file = File::open(path)?;

// Read the JSON contents of the file as an instance of `PyFunction`.
let u = serde_json::from_reader(file)?;

// Return the `PyFunction`.
Ok(u)
}

#[test]
fn convert_test() {
println!("attempting to parse with serde");
let pf = read_code_from_file("../../file1.json").unwrap();
println!("{:?}", pf);
}


}

3 changes: 3 additions & 0 deletions languages/client/src/ast/notworking/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod function;

pub use self::function::*;
223 changes: 223 additions & 0 deletions languages/client/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
#[macro_use]
extern crate serde_derive;

extern crate encoding;
extern crate serde_json;
extern crate serde;

//mod pyast;
//mod ast;


use encoding::{Encoding, EncoderTrap};
use encoding::all::ASCII;
use std::error; //{env, error}
use std::net::TcpStream;
use std::io;
use std::str;
use std::io::prelude::*;
use std::io::BufWriter;
use std::fs::File;

fn check_file(command: &str,
mut stream: &mut TcpStream)
-> Result<String, Box<error::Error + Send + Sync>> {

/*
****************
* REQUEST AST *
****************
*/

//get string size (in bytes)
let mut string_size = command.len();
string_size = string_size + 1;

println!("sending {} bytes", string_size);

let string_size_str = string_size.to_string();

//encode buffer to send size
let mut string_size_bytes = try!(ASCII
.encode(&string_size_str, EncoderTrap::Strict)
.map_err(|x| x.into_owned()));
string_size_bytes.push('\r' as u8);

//prepare buffer to send message itself
let mut command_bytes = try!(ASCII
.encode(command, EncoderTrap::Strict)
.map_err(|x| x.into_owned()));
command_bytes.push('\r' as u8); //ending escape sequence

//send message size:
stream.write_all(&string_size_bytes).unwrap();

//receive message size ACK:
let mut ack_buf = [0u8; 8];
stream.read(&mut ack_buf).unwrap();
let ack_slice: &str = str::from_utf8(&mut ack_buf).unwrap(); //string slice
let ack_str = ack_slice.to_string(); //convert slice to string
println!("{}: server ackd", ack_str);


//send file path
stream.write_all(&command_bytes).unwrap();

//receive message length:
let mut buf = [0u8; 8]; //make it bigger if necessary
stream.read(&mut buf).unwrap();

//interpret the buffer contents into a string slice
//let mut cl = buf.clone();
let msg_len_slice: &str = str::from_utf8(&mut buf).unwrap(); //string slice
let mut msg_len_str = msg_len_slice.to_string(); //convert slice to string

/*
CLEAN STRING:
server might send message size smaller than buffer,
which is usually the case when the server is sending
the message size:

buffer: _ _ _ _ _ _ _ (bytes)
message: 1 2 _ _ _ _ _ (bytes)

(empty characters trail the meaningful characters)
if this is the case, we shrink the string using .truncate()
*/

let mut numeric_chars = 0;
for c in msg_len_str.chars() {
if c.is_numeric() == true {
numeric_chars = numeric_chars + 1;
}
}

//shrink:
msg_len_str.truncate(numeric_chars);

println!("receiving {} bytes", msg_len_str);

let mut remaining_data = msg_len_str.parse::<i32>().unwrap();
let mut accumulator: String = String::new();
let mut r = [0u8; 8]; //8 byte buffer

if remaining_data > 260
//big message; write to file
{

//format file name
// ../files/file1.py
let start = command.rfind('/').unwrap() as usize;
let end = command.rfind('.').unwrap() as usize;
let mut file_name = String::from(&command[start + 1..end]);
file_name.push_str(".json");
println!("{}", &command);
println!("{}", file_name);

//create a file
let mut file_buffer = BufWriter::new(File::create(file_name)?);

while remaining_data != 0 {
if remaining_data >= 8
//slab >= 8 byte buffer
{
let slab = stream.read(&mut r);
match slab {
Ok(n) => {
file_buffer.write(&mut r)?;
file_buffer.flush()?;
println!("wrote {} bytes to file", n);
remaining_data = remaining_data - n as i32;
}
_ => {}
}
} else
//slab < 8 byte buffer
{
let array_limit = (remaining_data as i32) - 1;
let slab = stream.read(&mut r);
match slab {
Ok(n) => {
let mut r_slice = &r[0..(array_limit as usize + 1)]; // fixes underreading
// caused by not using
// subprocess call on
// the server server
file_buffer.write(&mut r_slice)?;
file_buffer.flush()?;
println!("wrote {} bytes to file", n);
remaining_data = remaining_data - n as i32;
}
_ => {}
}
}
}
accumulator.push_str("response written to file");
} else {
//small message; receive as string
while remaining_data != 0 {
if remaining_data >= 8
//slab >= 8 byte buffer
{
let slab = stream.read(&mut r);
match slab {
Ok(n) => {
let r_slice = str::from_utf8(&mut r).unwrap(); //string slice
accumulator.push_str(r_slice);
println!("wrote {} bytes", n);
remaining_data = remaining_data - n as i32;
}
_ => {}
}
}
/*
option 1) receive and read a smaller buffer
option 2) receive and read same buffer; truncate it to the smaller slab size

since we cannot instantiate an array with a non-constant:
e.g.: let mut r = [0u8; remainingData];
it is better to just put the byte in the 8 byte buffer, and shrink it with
.truncate() method before pushing to the String
*/
else
//slab < 8 byte buffer
{
let slab = stream.read(&mut r);
match slab {
Ok(n) => {
let s_slice = str::from_utf8(&mut r).unwrap(); //string slice
let mut s_str = s_slice.to_string(); //convert slice to string
s_str.truncate(n);
accumulator.push_str(&s_str);
println!("wrote {} bytes", n);
remaining_data = remaining_data - n as i32;
}
_ => {}
}
}
}
}

let response = accumulator;
Ok(response)
}

fn main() {
//setup connection:
//let mut stream = TcpStream::connect("127.0.0.1:5555")
let mut stream = TcpStream::connect("127.0.0.1:5555") // try!(TcpStream::connect(HOST));
.expect("Couldn't connect to the server...");

loop {
println!("Type command:");
let stdin = io::stdin();
for line in stdin.lock().lines() {
let command = line.unwrap();
println!("message: {}", command);

match check_file(&command, &mut stream) {
Ok(response) => println!("response: {}", response),
Err(err) => println!("An error occurred: {}", err),
}
}
}
}
42 changes: 42 additions & 0 deletions languages/files/file1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
orderedPairsSet = set()

def sum(x,y):
return x + y

def div(x,y):
if (x % y == 0):
return True
else:
return False

def checkPair(x,y,p,q):
if(sum(x,y) > p and sum(x,y) < q and div(y,x)==True):
orderedPairsSet.add((x,y))
return True
else:
return False

def myRelation(p,q):
if(p < q and p > 3 and q > 4):
print("myRelation(%d, %d)" % (p,q))
x = 1
y = 2

checkPair(x,y,p,q)
while (x <= p and y <= q):
if (y+2 > q):
y = 2
x = x+2
checkPair(x,y,p,q)
else:
y = y+2
checkPair(x,y,p,q)

print("List:")
print(sorted(orderedPairsSet))

else:
print("invalid input")

myRelation(5,10)
myRelation(6,15)
11 changes: 11 additions & 0 deletions languages/parser/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "parser"
version = "0.1.0"
authors = ["lborg019 <[email protected]>"]

[dependencies]
serde = "1.0"
serde_derive = "1.0"

# serde_json is just for the example, not required in general
serde_json = "1.0"
Loading