Skip to content

Commit

Permalink
Merge pull request #24 from Rigidity/cat-example
Browse files Browse the repository at this point in the history
Cat example
  • Loading branch information
Rigidity committed Jul 8, 2024
2 parents 2409c71 + 8998743 commit e8d15fa
Show file tree
Hide file tree
Showing 19 changed files with 576 additions and 94 deletions.
10 changes: 10 additions & 0 deletions crates/rue-compiler/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct Ops {
eq: NodePtr,
gt_bytes: NodePtr,
sha256: NodePtr,
substr: NodePtr,
strlen: NodePtr,
concat: NodePtr,
add: NodePtr,
Expand Down Expand Up @@ -59,6 +60,7 @@ impl<'a> Codegen<'a> {
eq: allocator.new_small_number(9).unwrap(),
gt_bytes: allocator.new_small_number(10).unwrap(),
sha256: allocator.new_small_number(11).unwrap(),
substr: allocator.new_small_number(12).unwrap(),
strlen: allocator.new_small_number(13).unwrap(),
concat: allocator.new_small_number(14).unwrap(),
add: allocator.new_small_number(16).unwrap(),
Expand Down Expand Up @@ -96,6 +98,7 @@ impl<'a> Codegen<'a> {
Lir::Raise(value) => self.gen_raise(value),
Lir::Sha256(values) => self.gen_sha256(values),
Lir::Listp(value) => self.gen_listp(value),
Lir::Substr(value, start, end) => self.gen_substr(value, start, end),
Lir::Strlen(value) => self.gen_strlen(value),
Lir::PubkeyForExp(value) => self.gen_pubkey_for_exp(value),
Lir::Concat(values) => self.gen_concat(values),
Expand Down Expand Up @@ -208,6 +211,13 @@ impl<'a> Codegen<'a> {
self.list(&[self.ops.l, value])
}

fn gen_substr(&mut self, value: LirId, start: LirId, end: LirId) -> NodePtr {
let value = self.gen_lir(value);
let start = self.gen_lir(start);
let end = self.gen_lir(end);
self.list(&[self.ops.substr, value, start, end])
}

fn gen_strlen(&mut self, value: LirId) -> NodePtr {
let value = self.gen_lir(value);
self.list(&[self.ops.strlen, value])
Expand Down
30 changes: 30 additions & 0 deletions crates/rue-compiler/src/compiler/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pub fn builtins(db: &mut Database) -> Builtins {
let sha256 = sha256(db, &builtins);
let pubkey_for_exp = pubkey_for_exp(db, &builtins);
let divmod = divmod(db, &builtins);
let substr = substr(db, &builtins);

db.scope_mut(builtins.scope_id)
.define_symbol("sha256".to_string(), sha256);
Expand All @@ -73,6 +74,9 @@ pub fn builtins(db: &mut Database) -> Builtins {
db.scope_mut(builtins.scope_id)
.define_symbol("divmod".to_string(), divmod);

db.scope_mut(builtins.scope_id)
.define_symbol("substr".to_string(), substr);

builtins
}

Expand Down Expand Up @@ -144,3 +148,29 @@ fn divmod(db: &mut Database, builtins: &Builtins) -> SymbolId {
},
}))
}

fn substr(db: &mut Database, builtins: &Builtins) -> SymbolId {
let mut scope = Scope::default();
let value = db.alloc_symbol(Symbol::Parameter(builtins.bytes));
let start = db.alloc_symbol(Symbol::Parameter(builtins.int));
let end = db.alloc_symbol(Symbol::Parameter(builtins.int));
scope.define_symbol("value".to_string(), value);
scope.define_symbol("start".to_string(), start);
scope.define_symbol("end".to_string(), end);
let value_ref = db.alloc_hir(Hir::Reference(value, TextRange::default()));
let start_ref = db.alloc_hir(Hir::Reference(start, TextRange::default()));
let end_ref = db.alloc_hir(Hir::Reference(end, TextRange::default()));
let hir_id = db.alloc_hir(Hir::Substr(value_ref, start_ref, end_ref));
let scope_id = db.alloc_scope(scope);

db.alloc_symbol(Symbol::InlineFunction(Function {
scope_id,
hir_id,
ty: FunctionType {
param_types: vec![builtins.bytes, builtins.int, builtins.int],
rest: Rest::Nil,
return_type: builtins.bytes,
generic_types: Vec::new(),
},
}))
}
4 changes: 3 additions & 1 deletion crates/rue-compiler/src/compiler/expr/field_access_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,11 @@ impl Compiler<'_> {
type_id = self.db.alloc_type(Type::Optional(type_id));
}

let fields_hir_id = self.db.alloc_hir(Hir::Op(Op::Rest, old_value.hir_id));

Value::new(
self.compile_index(
old_value.hir_id,
fields_hir_id,
index,
index == fields.len() - 1 && variant_type.rest != Rest::Nil,
),
Expand Down
17 changes: 17 additions & 0 deletions crates/rue-compiler/src/compiler/expr/guard_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,23 @@ impl Compiler<'_> {
hir_id,
))
}
(Type::Nullable(inner), Type::Nil) => {
let hir_id = self.db.alloc_hir(Hir::Op(Op::Not, hir_id));

Some((
Guard::new(TypeOverride::new(to), TypeOverride::new(inner)),
hir_id,
))
}
(Type::Nullable(inner), _) if self.db.compare_type(to, inner).is_equal() => {
let hir_id = self.db.alloc_hir(Hir::Op(Op::Not, hir_id));
let hir_id = self.db.alloc_hir(Hir::Op(Op::Not, hir_id));

Some((
Guard::new(TypeOverride::new(to), TypeOverride::new(inner)),
hir_id,
))
}
_ => {
self.db.error(
ErrorKind::UnsupportedTypeGuard(self.type_name(from), self.type_name(to)),
Expand Down
6 changes: 6 additions & 0 deletions crates/rue-compiler/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@ impl Database {
Op::PubkeyForExp => format!("PubkeyForExp({})", self.dbg_hir(*hir_id)),
Op::BitwiseNot => format!("BitwiseNot({})", self.dbg_hir(*hir_id)),
},
Hir::Substr(start, end, string) => format!(
"Substr({}, {}, {})",
self.dbg_hir(*start),
self.dbg_hir(*end),
self.dbg_hir(*string)
),
Hir::Raise(hir_id) => format!(
"Raise({})",
hir_id
Expand Down
23 changes: 13 additions & 10 deletions crates/rue-compiler/src/dependency_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ impl<'a> GraphBuilder<'a> {
self.walk_hir(scope_id, lhs);
self.walk_hir(scope_id, rhs);
}
Hir::Substr(value, start, end) => {
self.walk_hir(scope_id, value);
self.walk_hir(scope_id, start);
self.walk_hir(scope_id, end);
}
Hir::Definition(child_scope_id, hir_id) => {
self.walk_definition(scope_id, child_scope_id, hir_id);
}
Expand Down Expand Up @@ -209,16 +214,9 @@ impl<'a> GraphBuilder<'a> {
.or_default()
.insert(parent_scope_id);

let parent_environment_id = self.graph.environments[&parent_scope_id];

let child_environment_id = self
.db
.alloc_env(Environment::binding(parent_environment_id));

self.graph
.environments
.insert(child_scope_id, child_environment_id);

let parent_env_id = self.graph.environments[&parent_scope_id];
let child_env_id = self.db.alloc_env(Environment::binding(parent_env_id));
self.graph.environments.insert(child_scope_id, child_env_id);
self.walk_hir(child_scope_id, hir_id);
}

Expand Down Expand Up @@ -383,6 +381,11 @@ impl<'a> GraphBuilder<'a> {
self.ref_hir(scope_id, lhs);
self.ref_hir(scope_id, rhs);
}
Hir::Substr(value, start, end) => {
self.ref_hir(scope_id, value);
self.ref_hir(scope_id, start);
self.ref_hir(scope_id, end);
}
Hir::Definition(scope_id, hir_id) => {
self.ref_hir(scope_id, hir_id);
}
Expand Down
7 changes: 7 additions & 0 deletions crates/rue-compiler/src/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ impl Environment {
}

pub fn capture(&mut self, symbol_id: SymbolId) {
if self.parent.is_some() {
return;
}
self.captures.insert(symbol_id);
}

Expand All @@ -63,6 +66,10 @@ impl Environment {
self.parent
}

pub fn parent_mut(&mut self) -> &mut Option<EnvironmentId> {
&mut self.parent
}

pub fn build(&self) -> IndexSet<SymbolId> {
let mut symbol_ids = IndexSet::new();
symbol_ids.extend(self.definitions.iter().copied());
Expand Down
1 change: 1 addition & 0 deletions crates/rue-compiler/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub enum Hir {
FunctionCall(HirId, Vec<HirId>, bool),
Op(Op, HirId),
BinaryOp(BinOp, HirId, HirId),
Substr(HirId, HirId, HirId),
Raise(Option<HirId>),
If(HirId, HirId, HirId),
}
Expand Down
1 change: 1 addition & 0 deletions crates/rue-compiler/src/lir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub enum Lir {
Sha256(Vec<LirId>),
Listp(LirId),
Strlen(LirId),
Substr(LirId, LirId, LirId),
PubkeyForExp(LirId),
If(LirId, LirId, LirId),
Not(LirId),
Expand Down
8 changes: 7 additions & 1 deletion crates/rue-compiler/src/lowerer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ impl<'a> Lowerer<'a> {
let rhs = self.lower_hir(env_id, rhs);
self.db.alloc_mir(Mir::BinaryOp(op, lhs, rhs))
}
Hir::Substr(hir_id, start, end) => {
let hir_id = self.lower_hir(env_id, hir_id);
let start = self.lower_hir(env_id, start);
let end = self.lower_hir(env_id, end);
self.db.alloc_mir(Mir::Substr(hir_id, start, end))
}
Hir::Raise(value) => {
let value = value.map(|hir_id| self.lower_hir(env_id, hir_id));
self.db.alloc_mir(Mir::Raise(value))
Expand Down Expand Up @@ -220,7 +226,7 @@ impl<'a> Lowerer<'a> {
match self.db.symbol(symbol_id).clone() {
Symbol::Function(function) => self.lower_function(&function),
Symbol::Const(constant) => self.lower_hir(env_id, constant.hir_id),
Symbol::Let(binding) if self.graph.symbol_references(symbol_id) > 0 => {
Symbol::Let(binding) if self.graph.symbol_references(symbol_id) > 1 => {
self.lower_hir(env_id, binding.hir_id)
}
Symbol::Unknown
Expand Down
1 change: 1 addition & 0 deletions crates/rue-compiler/src/mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub enum Mir {
Pair(MirId, MirId),
Op(Op, MirId),
BinaryOp(BinOp, MirId, MirId),
Substr(MirId, MirId, MirId),
Raise(Option<MirId>),
If(MirId, MirId, MirId),
Run(MirId, MirId),
Expand Down
94 changes: 80 additions & 14 deletions crates/rue-compiler/src/optimizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ impl<'a> Optimizer<'a> {
};
handler(self, env_id, lhs, rhs)
}
Mir::Substr(value, start, end) => {
let value = self.opt_mir(env_id, value);
let start = self.opt_mir(env_id, start);
let end = self.opt_mir(env_id, end);
self.db.alloc_lir(Lir::Substr(value, start, end))
}
Mir::If(condition, then_block, else_block) => {
self.opt_if(env_id, condition, then_block, else_block)
}
Expand Down Expand Up @@ -106,16 +112,21 @@ impl<'a> Optimizer<'a> {
self.db.alloc_lir(Lir::Quote(value))
}

fn opt_path(&mut self, env_id: EnvironmentId, symbol_id: SymbolId) -> LirId {
let mut current_env_id = env_id;
let mut environment: Vec<SymbolId> = self.db.env(env_id).build().into_iter().collect();
fn opt_path(&mut self, mut env_id: EnvironmentId, symbol_id: SymbolId) -> LirId {
let mut environment = Vec::new();
let mut rest;

loop {
environment.extend(self.db.env(env_id).build());
rest = self.db.env(env_id).rest();

while let Some(parent_env_id) = self.db.env(current_env_id).parent() {
assert!(self.db.env(current_env_id).parameters().is_empty());
assert!(!self.db.env(current_env_id).rest());
let Some(parent_env_id) = self.db.env(env_id).parent() else {
break;
};

current_env_id = parent_env_id;
environment.extend(self.db.env(current_env_id).build());
assert!(self.db.env(env_id).parameters().is_empty());
assert!(!self.db.env(env_id).rest());
env_id = parent_env_id;
}

let index = environment
Expand All @@ -130,7 +141,7 @@ impl<'a> Optimizer<'a> {

let mut path = BigInt::one();

if !(index + 1 == environment.len() && self.db.env(env_id).rest()) {
if !(index + 1 == environment.len() && rest) {
path *= 2;
}

Expand Down Expand Up @@ -229,7 +240,18 @@ impl<'a> Optimizer<'a> {
fn opt_add(&mut self, env_id: EnvironmentId, lhs: MirId, rhs: MirId) -> LirId {
let lhs = self.opt_mir(env_id, lhs);
let rhs = self.opt_mir(env_id, rhs);
self.db.alloc_lir(Lir::Add(vec![lhs, rhs]))
let mut args = Vec::new();
if let Lir::Add(lhs) = self.db.lir(lhs) {
args.extend(lhs);
} else {
args.push(lhs);
}
if let Lir::Add(rhs) = self.db.lir(rhs) {
args.extend(rhs);
} else {
args.push(rhs);
}
self.db.alloc_lir(Lir::Add(args))
}

fn opt_subtract(&mut self, env_id: EnvironmentId, lhs: MirId, rhs: MirId) -> LirId {
Expand All @@ -241,7 +263,18 @@ impl<'a> Optimizer<'a> {
fn opt_multiply(&mut self, env_id: EnvironmentId, lhs: MirId, rhs: MirId) -> LirId {
let lhs = self.opt_mir(env_id, lhs);
let rhs = self.opt_mir(env_id, rhs);
self.db.alloc_lir(Lir::Mul(vec![lhs, rhs]))
let mut args = Vec::new();
if let Lir::Mul(lhs) = self.db.lir(lhs) {
args.extend(lhs);
} else {
args.push(lhs);
}
if let Lir::Mul(rhs) = self.db.lir(rhs) {
args.extend(rhs);
} else {
args.push(rhs);
}
self.db.alloc_lir(Lir::Mul(args))
}

fn opt_divide(&mut self, env_id: EnvironmentId, lhs: MirId, rhs: MirId) -> LirId {
Expand Down Expand Up @@ -316,7 +349,18 @@ impl<'a> Optimizer<'a> {
fn opt_concat(&mut self, env_id: EnvironmentId, lhs: MirId, rhs: MirId) -> LirId {
let lhs = self.opt_mir(env_id, lhs);
let rhs = self.opt_mir(env_id, rhs);
self.db.alloc_lir(Lir::Concat(vec![lhs, rhs]))
let mut args = Vec::new();
if let Lir::Concat(lhs) = self.db.lir(lhs) {
args.extend(lhs);
} else {
args.push(lhs);
}
if let Lir::Concat(rhs) = self.db.lir(rhs) {
args.extend(rhs);
} else {
args.push(rhs);
}
self.db.alloc_lir(Lir::Concat(args))
}

fn opt_point_add(&mut self, env_id: EnvironmentId, lhs: MirId, rhs: MirId) -> LirId {
Expand All @@ -338,13 +382,35 @@ impl<'a> Optimizer<'a> {
fn opt_any(&mut self, env_id: EnvironmentId, lhs: MirId, rhs: MirId) -> LirId {
let lhs = self.opt_mir(env_id, lhs);
let rhs = self.opt_mir(env_id, rhs);
self.db.alloc_lir(Lir::Any(vec![lhs, rhs]))
let mut args = Vec::new();
if let Lir::Any(lhs) = self.db.lir(lhs) {
args.extend(lhs);
} else {
args.push(lhs);
}
if let Lir::Any(rhs) = self.db.lir(rhs) {
args.extend(rhs);
} else {
args.push(rhs);
}
self.db.alloc_lir(Lir::Any(args))
}

fn opt_all(&mut self, env_id: EnvironmentId, lhs: MirId, rhs: MirId) -> LirId {
let lhs = self.opt_mir(env_id, lhs);
let rhs = self.opt_mir(env_id, rhs);
self.db.alloc_lir(Lir::All(vec![lhs, rhs]))
let mut args = Vec::new();
if let Lir::All(lhs) = self.db.lir(lhs) {
args.extend(lhs);
} else {
args.push(lhs);
}
if let Lir::All(rhs) = self.db.lir(rhs) {
args.extend(rhs);
} else {
args.push(rhs);
}
self.db.alloc_lir(Lir::All(args))
}

fn opt_not(&mut self, env_id: EnvironmentId, value: MirId) -> LirId {
Expand Down
Loading

0 comments on commit e8d15fa

Please sign in to comment.