Skip to content

Instantly share code, notes, and snippets.

@linkdd
Last active September 7, 2022 00:14
Show Gist options
  • Save linkdd/e7e1df556e20500b4b4b78bc23a18a30 to your computer and use it in GitHub Desktop.
Save linkdd/e7e1df556e20500b4b4b78bc23a18a30 to your computer and use it in GitHub Desktop.
Letlang Hello world program and its Rust output

Letlang Hello World

The Letlang compiler translates the Letlang code to Rust code.

The structure is as follow:

  • lib/src/std/
    • io.let (see 11_std_io.let)
  • examples/hello-world/
    • letproject.toml
    • src/
      • main.let (see 10_hello_main.let)
    • .llbuild/
      • Cargo.toml
      • executable/
        • Cargo.toml
        • src/
          • main.rs (see 20_executable_crate.rs)
      • modules/
        • lldep_hello_main/
          • Cargo.toml
          • src/
            • lib.rs (see 21_hello_main_crate.rs)
        • lldep_std_io/
          • Cargo.toml
          • src/
            • lib.rs (see 22_std_io_crate.rs)

screenshot

module hello::main;
import std::io;
pub func main() -> @ok {
std::io::println("hello world");
}
module std::io;
effect __io_println(msg: string) -> @ok | (@error, atom);
pub func println(msg: string) -> @ok | (@error, atom) {
perform __io_println(msg);
}
use llcore_runtime::api::*;
use lldep_hello_main::symbol_main;
fn main() -> Result<()> {
let mut atom_table = AtomTable::new();
atom_table.register(Atom(0), "@ok");
atom_table.register(Atom(1), "@error");
atom_table.register(Atom(2), "@type_error");
atom_table.register(Atom(3), "@normal");
let node = Node::new(atom_table);
let main_func = Box::new(symbol_main::func_main {});
node.run(main_func)
}
pub(crate) use llcore_runtime::api::*;
pub(crate) use lldep_std_io;
#[allow(non_snake_case)]
pub mod symbol_main {
use super::*;
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, PartialEq)]
pub struct func_main {}
impl Function for func_main {
fn call(&self, context: Arc<Mutex<TaskContext>>, args: Vec<Value>) -> FunctionContinuation {
async fn code_block(
co: FunctionCoroutine,
context: Arc<Mutex<TaskContext>>,
args: Vec<Value>,
) -> Value {
helpers::assert_param_count(&co, context.clone(), 0, args.len()).await;
let return_type = ValueType {
llval: Value::Atom(Atom(0)),
};
let result = async {
let func = lldep_std_io::symbol_println::func_println {};
let args: Vec<Value> = vec![Value::String("hello world".to_string())];
helpers::call_function(&co, context.clone(), &func, args).await
}
.await;
helpers::assert_type(&co, context.clone(), &return_type, &result).await;
result
}
FunctionContinuation::new_boxed(|co| code_block(co, context, args))
}
}
}
pub(crate) use llcore_runtime::api::*;
#[allow(non_snake_case)]
pub(crate) mod symbol___io_println {
use super::*;
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, PartialEq)]
pub struct effect___io_println;
#[async_trait]
impl Effect for effect___io_println {
async fn call(
&self,
context: Arc<Mutex<TaskContext>>,
co: &FunctionCoroutine,
args: Vec<Value>,
) -> Value {
helpers::assert_param_count(&co, context.clone(), 1, args.len()).await;
let paramtype_0 = StringType {};
let paramval_0 = &args[0];
helpers::assert_type(&co, context.clone(), &paramtype_0, &paramval_0).await;
let result = co
.yield_(FunctionInterruption::Effect {
name: "__io_println".to_string(),
args,
})
.await;
let return_type = OneOfType {
lltypes: vec![
Box::new(ValueType {
llval: Value::Atom(Atom(0)),
}),
Box::new(TupleType {
members_types: vec![
Box::new(ValueType {
llval: Value::Atom(Atom(1)),
}),
Box::new(AtomType {}),
],
}),
],
};
helpers::assert_type(&co, context.clone(), &return_type, &result).await;
result
}
}
}
#[allow(non_snake_case)]
pub mod symbol_println {
use super::*;
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, PartialEq)]
pub struct func_println {}
impl Function for func_println {
fn call(&self, context: Arc<Mutex<TaskContext>>, args: Vec<Value>) -> FunctionContinuation {
async fn code_block(
co: FunctionCoroutine,
context: Arc<Mutex<TaskContext>>,
args: Vec<Value>,
) -> Value {
helpers::assert_param_count(&co, context.clone(), 1, args.len()).await;
let paramtype_0 = StringType {};
let paramval_0 = &args[0];
helpers::assert_type(&co, context.clone(), &paramtype_0, &paramval_0).await;
let return_type = OneOfType {
lltypes: vec![
Box::new(ValueType {
llval: Value::Atom(Atom(0)),
}),
Box::new(TupleType {
members_types: vec![
Box::new(ValueType {
llval: Value::Atom(Atom(1)),
}),
Box::new(AtomType {}),
],
}),
],
};
let result = async {
let effect = symbol___io_println::effect___io_println {};
let args: Vec<Value> = vec![paramval_0.clone()];
effect.call(context.clone(), &co, args).await
}
.await;
helpers::assert_type(&co, context.clone(), &return_type, &result).await;
result
}
FunctionContinuation::new_boxed(|co| code_block(co, context, args))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment