-
Notifications
You must be signed in to change notification settings - Fork 13
Add support for Array Type Checker #105
Changes from 1 commit
21ce794
e12de36
04db3f1
07bed03
a90e7b6
4fff6b4
c8588fd
54770b1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,84 +19,143 @@ | |
|
||
// Rust Library | ||
|
||
use std::ffi::CStr; | ||
use std::mem; | ||
use std::os::raw::c_char; | ||
|
||
// String comparision | ||
pub fn compute_size(type_string: &str) -> i32 { | ||
let mut bits = String::new(); | ||
//Index 2 and 3 represent the size | ||
bits.push(type_string.chars().nth(2).unwrap()); | ||
bits.push(type_string.chars().nth(3).unwrap()); | ||
let total_bits: i32 = bits.parse().unwrap(); | ||
let mut length_bits = String::new(); | ||
let index = 4; | ||
for i in 0..total_bits { | ||
let iterator = i as usize; | ||
length_bits.push(type_string.chars().nth(iterator + index).unwrap()); | ||
} | ||
//Convert size to i32 for integer comparision | ||
let size: i32 = length_bits.parse().unwrap(); | ||
return size; | ||
} | ||
|
||
pub fn calculate_type_priority(type_string: &str) -> i32 { | ||
let mut priority = 0; | ||
match type_string.chars().nth(1) { | ||
Some('C') => priority = 4, | ||
Some('B') => priority = 1, | ||
Some('F') | Some('I') => priority = 8, | ||
Some('A') => priority = 16, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add a comment defining the char to type mapping? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. Please check it! |
||
_ => println!("Unsupported type"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Return error Result for unsupported types There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about this?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd return a std::result::Result from the function. The lib.rs side can check the return and panic if required. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
} | ||
return priority; | ||
} | ||
|
||
/* | ||
* Algorithm for checking whether typecast is possible from source to destination | ||
* Index 0 - represents data structure | ||
* Index 1 - represents type | ||
* Index 2 and 3 - represents bits followed by its size | ||
* */ | ||
#[no_mangle] | ||
pub extern "C" fn is_same_type(src_type : *const c_char, dest_type : *const c_char) -> bool | ||
{ | ||
return src_type == dest_type; | ||
pub extern "C" fn is_same_type(src_type: *const c_char, dest_type: *const c_char) -> bool { | ||
//Conversion to CStr | ||
let source_cstr: &CStr = unsafe { CStr::from_ptr(src_type) }; | ||
let dest_cstr: &CStr = unsafe { CStr::from_ptr(dest_type) }; | ||
Comment on lines
+38
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
//Conversion to rust strings | ||
let source: String = source_cstr.to_str().unwrap().to_owned(); | ||
let destination: String = dest_cstr.to_str().unwrap().to_owned(); | ||
//If type strings are same | ||
if source == destination { | ||
return true; | ||
} | ||
//Index 0 represents type of data structure | ||
if source.chars().nth(0) != destination.chars().nth(0) { | ||
return false; | ||
} | ||
let mut src_priority = 0; | ||
let mut dest_priority = 0; | ||
match source.chars().nth(0) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Define these magic numbers for bit positions as constants. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you elaborate a bit more in this suggestion? Do you mean to use below snippet instead -
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no.. I mean define the string indexes as constants like:
Hope that makes sense? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. Makes sense. I have used
I will push this snippet along with other changes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It took some time, but I was able to come up with following code. Please do the research on rust language best practices in the future. extern crate num;
extern crate num_derive;
use num::FromPrimitive;
use num_derive::FromPrimitive;
const ARRAY_MEMBER_TYPE_INDEX: usize = 2;
#[derive(Debug, PartialEq, FromPrimitive)]
#[repr(u32)]
enum BalType {
Nil = 'N' as u32,
Boolean = 'B' as u32,
Int = 'I' as u32,
Float = 'F' as u32,
Decimal = 'D' as u32,
String = 'S' as u32,
Array = 'A' as u32,
Any = 'X' as u32,
}
pub fn type_size(type_string: &str) -> i32 {
let type_char = type_string.chars().nth(ARRAY_MEMBER_TYPE_INDEX)
.unwrap_or_else(|| panic!("illegle type discripor '{}', wrong length", type_string));
let bal_type = FromPrimitive::from_u32(type_char as u32)
.unwrap_or_else(|| panic!("illegle type tag '{}' in type discripor '{}'", type_char, type_string));
match bal_type {
BalType::Boolean => { 1 }
BalType::Int | BalType::Float => { 8 }
BalType::String => { 12 }
BalType::Any => { 16 }
_ => { unimplemented!("type_size for '{:?}'", bal_type) }
}
} Cargo.toml [dependencies]
num = "0.3"
num-traits = "0.2"
num-derive = "0.3" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for the snippet! Sure. I will follow it in next tasks! Let me modify other functions to follow above points! |
||
Some('A') => { | ||
if source.chars().nth(1) != destination.chars().nth(1) { | ||
src_priority = calculate_type_priority(&source); | ||
dest_priority = calculate_type_priority(&destination); | ||
} | ||
// If source type is bigger than destination, type cast is not possible | ||
if src_priority > dest_priority { | ||
return false; | ||
} | ||
let src_size: i32 = compute_size(&source); | ||
let dest_size: i32 = compute_size(&destination); | ||
if src_size > dest_size { | ||
return false; | ||
} | ||
} | ||
_ => println!("Unsupported data structure"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unsupported should fail check. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. Done. |
||
} | ||
//If all the checks are passed, type cast from source to destination is valid | ||
return true; | ||
} | ||
|
||
// Prints 64 bit signed integer | ||
#[no_mangle] | ||
pub extern "C" fn print64(num64 : i64) | ||
{ | ||
println!("{}", num64); | ||
pub extern "C" fn print64(num64: i64) { | ||
println!("{}", num64); | ||
} | ||
|
||
// Prints 32 bit signed integer | ||
#[no_mangle] | ||
pub extern "C" fn print32(num32 : i32) | ||
{ | ||
println!("{}", num32); | ||
pub extern "C" fn print32(num32: i32) { | ||
println!("{}", num32); | ||
} | ||
|
||
// Prints 16 bit signed integer | ||
#[no_mangle] | ||
pub extern "C" fn print16(num16 : i16) | ||
{ | ||
println!("{}", num16); | ||
pub extern "C" fn print16(num16: i16) { | ||
println!("{}", num16); | ||
} | ||
|
||
// Prints 8 bit signed integer | ||
#[no_mangle] | ||
pub extern "C" fn print8(num8 : i8) | ||
{ | ||
println!("{}", num8); | ||
pub extern "C" fn print8(num8: i8) { | ||
println!("{}", num8); | ||
} | ||
|
||
// Prints 64 bit unsigned integer | ||
#[no_mangle] | ||
pub extern "C" fn printu64(num64 : u64) | ||
{ | ||
println!("{}", num64); | ||
pub extern "C" fn printu64(num64: u64) { | ||
println!("{}", num64); | ||
} | ||
|
||
// Prints 32 bit unsigned integer | ||
#[no_mangle] | ||
pub extern "C" fn printu32(num32 : u32) | ||
{ | ||
println!("{}", num32); | ||
pub extern "C" fn printu32(num32: u32) { | ||
println!("{}", num32); | ||
} | ||
|
||
// Prints 16 bit unsigned integer | ||
#[no_mangle] | ||
pub extern "C" fn printu16(num16 : u16) | ||
{ | ||
println!("{}", num16); | ||
pub extern "C" fn printu16(num16: u16) { | ||
println!("{}", num16); | ||
} | ||
|
||
// Prints 8 bit unsigned integer | ||
#[no_mangle] | ||
pub extern "C" fn printu8(num8 : u8) | ||
{ | ||
println!("{}", num8); | ||
pub extern "C" fn printu8(num8: u8) { | ||
println!("{}", num8); | ||
} | ||
|
||
// Prints 64 bit float | ||
#[no_mangle] | ||
pub extern "C" fn printf64(num64 : f64) | ||
{ | ||
println!("{}", num64); | ||
pub extern "C" fn printf64(num64: f64) { | ||
println!("{}", num64); | ||
} | ||
|
||
// Prints 32 bit float | ||
#[no_mangle] | ||
pub extern "C" fn printf32(num32 : f32) | ||
{ | ||
println!("{}", num32); | ||
pub extern "C" fn printf32(num32: f32) { | ||
println!("{}", num32); | ||
} | ||
|
||
#[no_mangle] | ||
|
@@ -125,7 +184,7 @@ pub extern "C" fn int_array_store(arr_ptr: *mut Vec<*mut i32>, n: i32, ref_ptr: | |
|
||
#[no_mangle] | ||
pub extern "C" fn int_array_load(arr_ptr: *mut Vec<*mut i32>, n: i32) -> *mut i32 { | ||
let arr = unsafe { Box::from_raw(arr_ptr)}; | ||
let arr = unsafe { Box::from_raw(arr_ptr) }; | ||
let n_size = n as usize; | ||
let return_val = arr[n_size]; | ||
mem::forget(arr); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to handle unbounded Array sizes?