Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

Commit

Permalink
Make String to be a wrapper above ref (#87)
Browse files Browse the repository at this point in the history
* Make string to be wrapper around pointer

* Print present types
  • Loading branch information
gavrilikhin-d authored Mar 6, 2024
1 parent a0b2d51 commit 4df56dd
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 27 deletions.
4 changes: 2 additions & 2 deletions src/ir/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ impl<'llvm> Types<'llvm> {
}

/// LLVM IR for [`String`](Type::String) type
pub fn string(&self) -> PointerType<'llvm> {
self.opaque("String")
pub fn string(&self) -> StructType<'llvm> {
self.with_impl("String")
}

/// LLVM IR for C string type
Expand Down
5 changes: 4 additions & 1 deletion src/runtime/ppl.ppl
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,11 @@ fn destroy <:Rational>
//=================================
// String
//=================================
type StringImpl

@builtin
type String
type String:
impl: Reference<StringImpl>

/// Concatenate 2 strings
@mangle_as("string_plus_string")
Expand Down
14 changes: 9 additions & 5 deletions src/runtime/src/integer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use rug::{ops::Pow, Integer};

use crate::Rational;
use crate::{Rational, String};

/// Construct [`Integer`](ppl::semantics::Type::Integer) from i32
#[no_mangle]
Expand Down Expand Up @@ -41,11 +41,13 @@ pub extern "C" fn integer_from_c_string(str: *const i8) -> *mut Integer {
/// fn <:Integer> as String -> String
/// ```
#[no_mangle]
pub extern "C" fn integer_as_string(i: *const Integer) -> *mut String {
pub extern "C" fn integer_as_string(i: *const Integer) -> String {
let i = unsafe { i.as_ref().unwrap() };
let str = i.to_string();
let boxed = Box::new(str);
Box::into_raw(boxed)
String {
data: Box::into_raw(boxed),
}
}

/// Negates integer
Expand Down Expand Up @@ -218,9 +220,11 @@ pub extern "C" fn i32_plus_i32(x: i32, y: i32) -> i32 {
/// fn <:I32> as String -> String
/// ```
#[no_mangle]
pub extern "C" fn i32_as_string(x: i32) -> *mut String {
pub extern "C" fn i32_as_string(x: i32) -> String {
let boxed = Box::new(x.to_string());
Box::into_raw(boxed)
String {
data: Box::into_raw(boxed),
}
}

/// # PPL
Expand Down
8 changes: 5 additions & 3 deletions src/runtime/src/memory.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use libc::{c_void, malloc};
use rug::Integer;

use crate::{integer_from_i64, integer_from_u64, Type};
use crate::{integer_from_i64, integer_from_u64, String, Type};

#[repr(C)]
pub struct MemoryAddress {
Expand All @@ -13,12 +13,14 @@ pub struct MemoryAddress {
/// fn <address: MemoryAddress> as String -> String
/// ```
#[no_mangle]
pub extern "C" fn memory_address_as_string(address: MemoryAddress) -> *mut String {
pub extern "C" fn memory_address_as_string(address: MemoryAddress) -> String {
let value = unsafe { address.value.as_ref().unwrap() };

let hex = format!("0x{}", value.to_string_radix(16).to_uppercase());
let boxed = Box::new(hex);
Box::into_raw(boxed)
String {
data: Box::into_raw(boxed),
}
}

/// # PPL
Expand Down
10 changes: 7 additions & 3 deletions src/runtime/src/rational.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use rug::{ops::Pow, Integer};

use crate::String;

/// Rational number.
/// Wrapper around pointer to [`rug::Rational`].
///
Expand Down Expand Up @@ -36,11 +38,13 @@ pub extern "C" fn rational_from_c_string(str: *const i8) -> Rational {
/// fn <:Rational> as String -> String
/// ```
#[no_mangle]
pub extern "C" fn rational_as_string(r: Rational) -> *mut String {
pub extern "C" fn rational_as_string(r: Rational) -> String {
let value = unsafe { r.data.as_ref().unwrap() };

let boxed = Box::new(maybe_to_decimal_string(value));
Box::into_raw(boxed)
String {
data: Box::into_raw(boxed),
}
}

/// Negates rational
Expand Down Expand Up @@ -145,7 +149,7 @@ pub extern "C" fn destroy_rational(x: Rational) {
let _ = unsafe { Box::from_raw(x.data) };
}

pub fn maybe_to_decimal_string(r: &rug::Rational) -> String {
pub fn maybe_to_decimal_string(r: &rug::Rational) -> std::string::String {
let mut denom = r.denom().clone();
let pow2 = denom.remove_factor_mut(&Integer::from(2));
let pow5 = denom.remove_factor_mut(&Integer::from(5));
Expand Down
42 changes: 31 additions & 11 deletions src/runtime/src/string.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
use std::io::Write;

/// PPL's String type.
/// Wrapper around pointer to [`std::string::String`].
///
/// # PPL
/// ```no_run
/// type StringImpl
///
/// @builtin
/// type String:
/// impl: Reference<StringImpl>
/// ```
#[repr(C)]
pub struct String {
pub data: *mut std::string::String,
}

/// Construct [`String`](ppl::semantics::Type::String) from a C string
/// and length
#[no_mangle]
pub extern "C" fn string_from_c_string_and_length(str: *const i8, _len: u64) -> *mut String {
pub extern "C" fn string_from_c_string_and_length(str: *const i8, _len: u64) -> String {
let c_str = unsafe { core::ffi::CStr::from_ptr(str) };
let str = c_str.to_str().unwrap();
let boxed = Box::new(str.to_string());
Box::into_raw(boxed)
String {
data: Box::into_raw(boxed),
}
}

/// Concatenate 2 string
Expand All @@ -17,12 +35,14 @@ pub extern "C" fn string_from_c_string_and_length(str: *const i8, _len: u64) ->
/// fn <:String> + <:String> -> None
/// ```
#[no_mangle]
pub extern "C" fn string_plus_string(x: *const String, y: *const String) -> *mut String {
let x = unsafe { x.as_ref().unwrap() };
let y = unsafe { y.as_ref().unwrap() };
pub extern "C" fn string_plus_string(x: String, y: String) -> String {
let x = unsafe { x.data.as_ref().unwrap() };
let y = unsafe { y.data.as_ref().unwrap() };

let boxed = Box::new(format!("{x}{y}"));
Box::into_raw(boxed)
String {
data: Box::into_raw(boxed),
}
}

/// Prints none value
Expand All @@ -32,8 +52,8 @@ pub extern "C" fn string_plus_string(x: *const String, y: *const String) -> *mut
/// fn print <str: String> -> None
/// ```
#[no_mangle]
pub extern "C" fn print_string(str: *const String) {
let str = unsafe { str.as_ref().unwrap() };
pub extern "C" fn print_string(str: String) {
let str = unsafe { str.data.as_ref().unwrap() };

print!("{str}");
std::io::stdout().flush().unwrap();
Expand All @@ -44,8 +64,8 @@ pub extern "C" fn print_string(str: *const String) {
/// fn destroy <:String>
/// ```
#[no_mangle]
pub extern "C" fn destroy_string(x: *mut String) {
debug_assert!(!x.is_null());
pub extern "C" fn destroy_string(x: String) {
debug_assert!(!x.data.is_null());

let _ = unsafe { Box::from_raw(x) };
let _ = unsafe { Box::from_raw(x.data) };
}
4 changes: 3 additions & 1 deletion src/runtime/src/type.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use rug::Integer;

use crate::String;

/// Runtime type information
///
/// # PPL
Expand All @@ -10,6 +12,6 @@ use rug::Integer;
/// ```
#[repr(C)]
pub struct Type {
pub name: *mut String,
pub name: String,
pub size: *mut Integer,
}
13 changes: 12 additions & 1 deletion src/semantics/contexts/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,18 @@ impl BuiltinTypes<'_> {
self.module
.types
.get(name)
.expect(format!("Builtin type `{name}` should be present").as_str())
.expect(
format!(
"Builtin type `{name}` should be present. Present types: {}",
self.module
.types
.iter()
.map(|t| t.0.clone())
.collect::<Vec<_>>()
.join(", ")
)
.as_str(),
)
.clone()
.into()
}
Expand Down

0 comments on commit 4df56dd

Please sign in to comment.