Skip to content

Added setup for core types #86

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

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
46 changes: 46 additions & 0 deletions examples/core/string.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#[std]
#[memory(262144)]

const MALE = true;
const FEMALE = true;

struct Person {
let name: String,
age: num,
sex: bool;

fn man(name: String, age: num) -> Person {
return [name, age, MALE];
}

fn woman(name: String, age: num) -> Person {
return [name, age, FEMALE];
}

fn puts(self: &Person) {
putstr((self->name)->contents);
putstr(" is ");
putnum(self->age);
putstr(" years old, and is a ");
putstr((self->sex)? "man" : "woman");
}

fn putln(self: &Person) {
self.puts(); putchar('\n');
}
}


fn main() {
let s = String::from("Hello,");
putstrln(s->contents);
for i in 0..1000 {
s.cats(String::from(" world!"));
}
putstrln(s->contents);

for i in 0..1000 {
let adam = Person::man(String::from("Adam"), 18);
adam.puts();
}
}
6 changes: 6 additions & 0 deletions examples/import/lib/all.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Include string library
#[import("test.ok")]
#[import("test.ok")]
#[import("test.ok")]
#[import("test.ok")]
#[import("test.ok")]
3 changes: 3 additions & 0 deletions examples/import/lib/test.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@


fn test() -> &char { return "Import works!"; }
6 changes: 6 additions & 0 deletions examples/import/main.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#[std]
#[import("lib/all.ok")]

fn main() {
putstrln(test());
}
61 changes: 61 additions & 0 deletions examples/std/time.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#[std]


struct Date {
let m: num,
d: num,
y: num;

fn now() -> Date {
return [
get_month_now() + 1,
get_day_now(),
get_year_now(),
];
}

fn puts(self: &Date) {
putnum(self->m);
putchar('\\');
putnum(self->d);
putchar('\\');
putnum(self->y);
}

fn putln(self: &Date) {
self.puts(); prend();
}
}


struct Time {
let h: num,
m: num,
s: num;

fn now() -> Time {
return [
get_hour_now(),
get_minute_now(),
get_second_now(),
];
}

fn puts(self: &Time) {
putnum(self->h);
putchar(':');
putnum(self->m);
putchar(':');
putnum(self->s);
}

fn putln(self: &Time) {
self.puts(); prend();
}
}


fn main() {
putstr("Today is "); Date::now().putln();
putstr("And the time is "); Time::now().putln();
}
76 changes: 76 additions & 0 deletions src/core.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@


extern fn __oak_core__memcpy as memcpy(dst: &char, src: &char, size: num);
extern fn __oak_core__memset as memset(dst: &char, val: num, size: num);
extern fn __oak_core__strlen as strlen(src: &char) -> num;
extern fn __oak_core__strcpy as strcpy(dst: &char, src: &char);


fn realloc(src: &char, old_size: num, new_size: num) -> &char {
let dst = alloc(new_size) as &char;
let copy_size = 0;
if old_size < new_size { memcpy(dst, src, old_size) }
else { memcpy(dst, src, new_size) }

free src: old_size;
return dst;
}

struct String {
let contents: &char,
len: num;

///
/// Constructors
///
fn new() -> String { return [alloc(1), 0] }
fn from(src: &char) -> String {
let len = strlen(src);
let contents = alloc(len + 1) as &char;
strcpy(contents, src);
return [contents, len]
}


///
/// Getters
///
fn size(self: &String) -> num { return (self->len) + 1 }


///
/// Methods
///
fn grow(self: &String, d_size: num) {
let size = self.size();
self->contents = realloc(self->contents, size, size + d_size);
self->len += d_size;
}

fn push(self: &String, ch: char) {
self.grow(1);
(self->contents)[(self->len) - 1] = ch;
}

fn cat(self: &String, other: &char) {
let len = strlen(other);
let old_len = self->len;
self.grow(len);
strcpy(&(self->contents)[old_len], other);
}

fn cats(self: &String, other: String) { self.cat(other->contents); }

///
/// Memory Management
///
fn copy(self: &String) -> String {
let copy_str = alloc(self.size()) as &char;
memcpy(copy_str, self->contents, self.size());
return [copy_str, self->len]
}

fn drop(self: &String) {
free self->contents: self.size();
}
}
11 changes: 0 additions & 11 deletions src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,6 @@ impl HirProgram {
*memory_size
}

pub fn use_std(&self) -> bool {
for decl in self.get_declarations() {
match decl {
HirDeclaration::NoStd => return false,
HirDeclaration::RequireStd => return true,
_ => {}
}
}
false
}

pub fn generate_docs(
&self,
filename: String,
Expand Down
45 changes: 15 additions & 30 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,45 +118,30 @@ pub fn compile(
) -> Result<()> {
// Get the TIR code for the user's Oak code
let mut tir = parse(filename, input);
// Convert the TIR to HIR
let mut hir = match tir.compile(cwd) {
Ok(output) => output,
Err(e) => print_compile_error(e),
};

// Add the core library code to the users code
hir.extend_declarations(
match parse("core.ok", include_str!("core.ok")).compile(cwd) {
Ok(output) => output,
Err(e) => print_compile_error(e),
}
.get_declarations(),
);
tir.extend(parse("core.ok", include_str!("core.ok")));

// If the user specifies that they want to include the standard library
if hir.use_std() {
// Then add the standard library code to the users code
hir.extend_declarations(
match parse("std.ok", include_str!("std.ok")).compile(cwd) {
Ok(output) => output,
Err(e) => print_compile_error(e),
}
.get_declarations(),
);
if tir.use_std() {
tir.extend(parse("std.ok", include_str!("std.ok")));
}

match hir.compile(cwd, &mut get_predefined_constants(&target)) {
Ok(mir) => match mir.assemble() {
Ok(asm) => match asm.assemble(&target) {
Ok(result) => target.compile(if hir.use_std() {
target.core_prelude() + &target.std() + &result + &target.core_postlude()
} else {
target.core_prelude() + &result + &target.core_postlude()
}),
match tir.compile(cwd) {
Ok(mut hir) => match hir.compile(cwd, &mut get_predefined_constants(&target)) {
Ok(mir) => match mir.assemble() {
Ok(asm) => match asm.assemble(&target) {
Ok(result) => target.compile(if tir.use_std() {
target.core_prelude() + &target.std() + &result + &target.core_postlude()
} else {
target.core_prelude() + &result + &target.core_postlude()
}),
Err(e) => print_compile_error(e),
},
Err(e) => print_compile_error(e),
},
Err(e) => print_compile_error(e),
},
}
Err(e) => print_compile_error(e),
}
}
Expand Down
27 changes: 22 additions & 5 deletions src/std.ok
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
///
/// Time
///

extern fn prend();
extern fn prs as putstr(s: &char);
extern fn prn as putnum(n: num);
extern fn prc as putchar(ch: char);
extern fn getch as get_char() -> char;
// Date
extern fn __oak_std__get_month_now as get_month_now() -> num;
extern fn __oak_std__get_day_now as get_day_now() -> num;
extern fn __oak_std__get_year_now as get_year_now() -> num;

// Time
extern fn __oak_std__get_hour_now as get_hour_now() -> num;
extern fn __oak_std__get_minute_now as get_minute_now() -> num;
extern fn __oak_std__get_second_now as get_second_now() -> num;


///
/// IO
///
extern fn __oak_std__prend as prend();
extern fn __oak_std__putstr as putstr(s: &char);
extern fn __oak_std__putnum as putnum(n: num);
extern fn __oak_std__putchar as putchar(ch: char);
extern fn __oak_std__get_char as get_char() -> char;

fn putstrln(s: &char) -> void { putstr(s); prend(); }

Expand Down
12 changes: 6 additions & 6 deletions src/target/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,26 +134,26 @@ impl Target for C {
match child.stdin.as_mut() {
Some(stdin) => {
if let Err(error) = stdin.write_all(code.as_bytes()) {
return Result::Err(Error::new(
return Err(Error::new(
ErrorKind::Other,
"unable to open write to child stdin",
));
}
}
None => {
return Result::Err(Error::new(ErrorKind::Other, "unable to open child stdin"))
return Err(Error::new(ErrorKind::Other, "unable to open child stdin"))
}
}

match child.wait_with_output() {
Ok(_) => return Result::Ok(()),
return match child.wait_with_output() {
Ok(_) => Ok(()),
Err(_) => {
return Result::Err(Error::new(ErrorKind::Other, "unable to read child output"))
Err(Error::new(ErrorKind::Other, "unable to read child output"))
}
}
} else {
// child failed to execute
Result::Err(Error::new(
Err(Error::new(
ErrorKind::Other,
"unable to spawn child gcc proccess",
))
Expand Down
41 changes: 41 additions & 0 deletions src/target/core/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,3 +297,44 @@ void machine_sign(machine *vm) {
}


#include <string.h>

void __oak_core__memcpy(machine *vm) {
int dst = machine_pop(vm),
src = machine_pop(vm),
size = machine_pop(vm);

memcpy(&vm->memory[dst], &vm->memory[src], size * sizeof(double));
}

void __oak_core__memset(machine *vm) {
int dst = machine_pop(vm);
double val = machine_pop(vm);
int size = machine_pop(vm);

for (int i=0; i<size; i++)
vm->memory[dst+i] = val;
}

void __oak_core__strlen(machine *vm) {
int i, src = machine_pop(vm);
// memet(&vm->memory[dst], val, size * sizeof(double));
for (i=0; vm->memory[src+i]; i++) {}
machine_push(vm, i);
}

void __oak_core__strcpy(machine *vm) {
int i,
dst = machine_pop(vm),
src = machine_pop(vm);

machine_push(vm, src);
__oak_core__strlen(vm);
int len = machine_pop(vm);

machine_push(vm, len);
machine_push(vm, src);
machine_push(vm, dst);
__oak_core__memcpy(vm);
vm->memory[dst+len] = 0.0;
}
Loading