Skip to content

Commit

Permalink
New functions
Browse files Browse the repository at this point in the history
  • Loading branch information
nyzd committed Feb 11, 2024
1 parent 4c4ef39 commit 1cb30cb
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 32 deletions.
38 changes: 33 additions & 5 deletions figc/src/codegen/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
ConstStatement, ExportStatement, Expression, ExternalStatement, FunctionMeta,
FunctionStatement, Identifier, IfExpr, IndexExpr, InfixExpr, Integer, LetStatement,
LoopStatement, Program, RefValue, ReturnStatement, SetStatement, Statement, StringExpr,
StructStatement,
StructStatement, PrefixExpr,
},
types::types::Type,
};
Expand Down Expand Up @@ -198,6 +198,27 @@ impl<'a> Instructions<'a> for BooleanExpr {
}
}

impl<'a> Instructions<'a> for PrefixExpr {
fn generate_instructions(&self, _ctx: &'a mut Context) -> CResult<Vec<Instruction>> {
todo!();
//let mut result: Vec<Instruction> = vec![];

//let right_side = self.right.generate_instructions(ctx)?;

//result.extend(right_side);

//match self.operator {
// Token::Minus => {
// result.push(Instruction::F32Neg);
// }

// _ => panic!("Just - operation allowed"),
//}

//Ok(result)
}
}

impl<'a> Instructions<'a> for InfixExpr {
fn generate_instructions(&self, ctx: &'a mut Context) -> CResult<Vec<Instruction>> {
let mut result: Vec<Instruction> = vec![];
Expand All @@ -224,6 +245,7 @@ impl<'a> Instructions<'a> for ExternalStatement {
fn generate_instructions(&self, ctx: &'a mut Context) -> CResult<Vec<Instruction>> {
for func in &self.body.function_types {
let (param_types, result_type) = func.types()?;

let type_id = ctx
.type_ctx
.new_function_type(param_types.clone(), result_type);
Expand Down Expand Up @@ -265,15 +287,20 @@ impl<'a> Instructions<'a> for BuiltinStatement {

ctx.code_ctx.add_local(ValType::I32);
ctx.code_ctx.new_function_code(malloc(), "malloc".into());

// TODO: Add this to export generate_instructions functions
ctx.export_ctx
.export_function(&"malloc".to_owned(), type_index);
}

"free" => {
let type_index = ctx.type_ctx.new_function_type(vec![ValType::I32], vec![]);
panic!("free(size: i32); Not working well !");
//let type_index = ctx.type_ctx.new_function_type(vec![ValType::I32], vec![]);

ctx.function_ctx
.new_function(type_index, "free".to_string(), vec![]);
//ctx.function_ctx
// .new_function(type_index, "free".to_string(), vec![]);

ctx.code_ctx.new_function_code(free(), "free".into());
//ctx.code_ctx.new_function_code(free(), "free".into());
}

_ => todo!(),
Expand Down Expand Up @@ -465,6 +492,7 @@ impl<'a> Instructions<'a> for Expression {
match self {
Expression::Integer(int) => Ok(int.generate_instructions(ctx)?),
Expression::Infix(infix) => Ok(infix.generate_instructions(ctx)?),
Expression::Prefix(prefix) => Ok(prefix.generate_instructions(ctx)?),
Expression::Identifier(ident) => Ok(ident.generate_instructions(ctx)?),
Expression::Call(call) => Ok(call.generate_instructions(ctx)?),
Expression::String(s) => Ok(s.generate_instructions(ctx)?),
Expand Down
4 changes: 2 additions & 2 deletions figc/src/parser/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -598,8 +598,8 @@ impl<'a> Parse<'a> for IndexExpr {

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PrefixExpr {
operator: Token,
right: Box<Expression>,
pub(crate) operator: Token,
pub(crate) right: Box<Expression>,
}

impl<'a> Parse<'a> for PrefixExpr {
Expand Down
74 changes: 49 additions & 25 deletions figcli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ use std::io::{BufReader, Read, Write};
use std::path::PathBuf;
use std::process::exit;
use wasmer::{
imports, Function, FunctionEnv, FunctionEnvMut, Instance, Memory, Module, Store, Value, WasmPtr,
imports, Function, FunctionEnv, FunctionEnvMut, Instance, Memory, Module, Store, TypedFunction,
Value, WasmPtr,
};
use wasmprinter::print_bytes;

use std::io;
use std::io::prelude::*;
use std::net::TcpListener;

Expand Down Expand Up @@ -82,8 +81,10 @@ fn fig_compile_to_wasm(source: String, memory_offset: i32) -> (Vec<u8>, i32) {
(buf, ctx.memory_ctx.offset)
}

#[derive(Clone)]
struct Env {
memory: Option<Memory>,
alloc_func: Option<TypedFunction<i32, i32>>,
}

fn fig_print(mut env: FunctionEnvMut<Env>, p: WasmPtr<u8>) {
Expand All @@ -101,41 +102,54 @@ fn fig_print_char(c: i32) {
println!("{}", char::from(c as u8));
}

// fn(...) -> number of bytes actually read ( i32 ).
fn fig_read(mut env: FunctionEnvMut<Env>, fd: i32, buf_ptr: WasmPtr<u8>, until: u8) -> i32 {
match fd {
1 => {
let mut buf: Vec<u8> = Vec::new();
{
let stdin = io::stdin();
fn fig_read_file(mut env: FunctionEnvMut<Env>, addr: WasmPtr<u8>) -> i32 {
let (env_data, mut store) = env.data_and_store_mut();
let mut file_content: Vec<u8> = Vec::new();

// Don't use read_until
stdin.lock().read_until(until, &mut buf).unwrap();
}
{
let memory_view = env_data.memory.clone().unwrap().view(&mut store);

let (env_data, store) = env.data_and_store_mut();
let memory_view = env_data.memory.clone().unwrap().view(&store);
let addr_str = addr.read_utf8_string_with_nul(&memory_view).unwrap();

memory_view.write(buf_ptr.offset().into(), &buf).unwrap();

buf.len() as i32
}
let mut file = File::open(addr_str).unwrap();

filedes => panic!("File descriptor {} is not supported!", filedes),
file.read_to_end(&mut file_content).unwrap();
}

let buf = env_data
.alloc_func
.clone()
.unwrap()
.call(&mut store, file_content.len() as i32 + 1)
.unwrap();

let memory_view = env_data.memory.clone().unwrap().view(&mut store);

let buf_ptr = WasmPtr::<u8>::new(buf as u32);
memory_view
.write(buf_ptr.offset() as u64, &file_content)
.unwrap();

buf
}

fn run_wasm(bytes: &Vec<u8>) {
let mut store = Store::default();
let module = Module::new(&store, bytes).unwrap();

let env = FunctionEnv::new(&mut store, Env { memory: None });
let env = FunctionEnv::new(
&mut store,
Env {
memory: None,
alloc_func: None,
},
);
let import_object = imports! {
"io" => {
"print_str" => Function::new_typed_with_env(&mut store, &env, fig_print),
"print_int" => Function::new_typed(&mut store, fig_print_int),
"print_char" => Function::new_typed(&mut store, fig_print_char),
"read_until" => Function::new_typed_with_env(&mut store, &env, fig_read),
"read_file" => Function::new_typed_with_env(&mut store, &env, fig_read_file),
}
};

Expand All @@ -150,24 +164,34 @@ fn run_wasm_server<'a>(bytes: &Vec<u8>, addr: &'a str, mem_offset: i32) {
let mut store = Store::default();
let module = Module::new(&store, bytes).unwrap();

let env = FunctionEnv::new(&mut store, Env { memory: None });
let env = FunctionEnv::new(
&mut store,
Env {
memory: None,
alloc_func: None,
},
);
let import_object = imports! {
"io" => {
"print_str" => Function::new_typed_with_env(&mut store, &env, fig_print),
"print_int" => Function::new_typed(&mut store, fig_print_int),
"print_char" => Function::new_typed(&mut store, fig_print_char),
"read_until" => Function::new_typed_with_env(&mut store, &env, fig_read),
"read_file" => Function::new_typed_with_env(&mut store, &env, fig_read_file),
}
};

let listener = TcpListener::bind(addr).unwrap();
//listener.set_nonblocking(false).unwrap();

for stream in listener.incoming() {
let instance = Instance::new(&mut store, &module, &import_object).unwrap();
let memory = instance.exports.get_memory("memory").unwrap().clone();
let mem_offset_glob = instance.exports.get_global("mem_offset").unwrap();
let alloc_func = instance
.exports
.get_typed_function(&store, "malloc")
.unwrap();
env.as_mut(&mut store).memory = Some(memory);
env.as_mut(&mut store).alloc_func = Some(alloc_func.clone());
let main_fn = instance.exports.get_function("main").unwrap();

let mut stream = stream.unwrap();
Expand Down

0 comments on commit 1cb30cb

Please sign in to comment.