mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
parent
0e5751c2b0
commit
d9b2c0cb00
@ -1,3 +1,5 @@
|
||||
let t = import "std/testing.ucg".asserts{};
|
||||
|
||||
let test_empty_mod = module {
|
||||
} => {
|
||||
};
|
||||
@ -68,3 +70,43 @@ assert {
|
||||
ok = embedded_mod{dep_value="Some"}.embedded_def{}.value == "None",
|
||||
desc = "embedded_mod{dep_value=\"Some\"}.embedded_def{}.value == \"None\"",
|
||||
};
|
||||
|
||||
let export_module = module {
|
||||
foo = "",
|
||||
} => (result) {
|
||||
let foo = mod.foo;
|
||||
|
||||
let result = {
|
||||
out_foo = foo,
|
||||
};
|
||||
};
|
||||
|
||||
assert t.ok{
|
||||
test = out_foo in export_module{foo="bar"},
|
||||
desc = "out_foo is in our output tuple",
|
||||
};
|
||||
|
||||
assert t.equal{
|
||||
left = export_module{foo="bar"},
|
||||
right = {out_foo = "bar"},
|
||||
};
|
||||
|
||||
let export_module_tuple = module {
|
||||
foo = "",
|
||||
} => ({quux = result.out_foo}) {
|
||||
let foo = mod.foo;
|
||||
|
||||
let result = {
|
||||
out_foo = foo,
|
||||
};
|
||||
};
|
||||
|
||||
assert t.ok{
|
||||
test = quux in export_module_tuple{foo="bar"},
|
||||
desc = "quux is in our output tuple",
|
||||
};
|
||||
|
||||
assert t.equal{
|
||||
left = export_module_tuple{foo="bar"},
|
||||
right = {quux = "bar"},
|
||||
};
|
@ -535,6 +535,7 @@ pub struct ModuleDef {
|
||||
pub scope: Option<Scope>,
|
||||
pub pos: Position,
|
||||
pub arg_set: FieldList,
|
||||
pub out_expr: Option<Box<Expression>>,
|
||||
pub arg_tuple: Option<Rc<Val>>,
|
||||
pub statements: Vec<Statement>,
|
||||
}
|
||||
@ -545,11 +546,16 @@ impl ModuleDef {
|
||||
scope: None,
|
||||
pos: pos.into(),
|
||||
arg_set: arg_set,
|
||||
out_expr: None,
|
||||
arg_tuple: None,
|
||||
statements: stmts,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_out_expr(&mut self, expr: Expression) {
|
||||
self.out_expr = Some(Box::new(expr));
|
||||
}
|
||||
|
||||
pub fn imports_to_absolute(&mut self, base: PathBuf) {
|
||||
let rewrite_import = |e: &mut Expression| {
|
||||
if let Expression::Include(ref mut def) = e {
|
||||
|
@ -1134,13 +1134,12 @@ impl<'a> FileBuilder<'a> {
|
||||
)));
|
||||
}
|
||||
|
||||
fn eval_copy(&self, def: &CopyDef, scope: &Scope) -> Result<Rc<Val>, Box<dyn Error>> {
|
||||
let v = self.eval_value(&def.selector, scope)?;
|
||||
if let &Val::Tuple(ref src_fields) = v.as_ref() {
|
||||
let child_scope = scope.spawn_child().set_curr_val(v.clone());
|
||||
return self.copy_from_base(&src_fields, &def.fields, &child_scope);
|
||||
}
|
||||
if let &Val::Module(ref mod_def) = v.as_ref() {
|
||||
fn eval_module_copy(
|
||||
&self,
|
||||
def: &CopyDef,
|
||||
mod_def: &ModuleDef,
|
||||
scope: &Scope,
|
||||
) -> Result<Rc<Val>, Box<dyn Error>> {
|
||||
let maybe_tpl = mod_def.clone().arg_tuple.unwrap().clone();
|
||||
if let &Val::Tuple(ref src_fields) = maybe_tpl.as_ref() {
|
||||
// 1. First we create a builder.
|
||||
@ -1154,8 +1153,7 @@ impl<'a> FileBuilder<'a> {
|
||||
let child_scope = scope.spawn_child().set_curr_val(maybe_tpl.clone());
|
||||
let mod_args = self.copy_from_base(src_fields, &def.fields, &child_scope)?;
|
||||
// put our copied parameters tuple in our builder under the mod key.
|
||||
let mod_key =
|
||||
PositionedItem::new_with_pos(String::from("mod"), Position::new(0, 0, 0));
|
||||
let mod_key = PositionedItem::new_with_pos(String::from("mod"), Position::new(0, 0, 0));
|
||||
match b.scope.build_output.entry(mod_key) {
|
||||
Entry::Occupied(e) => {
|
||||
return Err(error::BuildError::with_pos(
|
||||
@ -1176,9 +1174,15 @@ impl<'a> FileBuilder<'a> {
|
||||
}
|
||||
// 4. Evaluate all the statements using the builder.
|
||||
b.eval_stmts(&mod_def.statements)?;
|
||||
if let Some(ref expr) = mod_def.out_expr {
|
||||
// 5. Produce the out expression in the context of the statements
|
||||
// we evaluated previously.
|
||||
return b.eval_expr(expr, &b.scope);
|
||||
} else {
|
||||
// 5. Take all of the bindings in the module and construct a new
|
||||
// tuple using them.
|
||||
return Ok(b.get_outputs_as_val());
|
||||
}
|
||||
} else {
|
||||
return Err(error::BuildError::with_pos(
|
||||
format!(
|
||||
@ -1191,6 +1195,16 @@ impl<'a> FileBuilder<'a> {
|
||||
.to_boxed());
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_copy(&self, def: &CopyDef, scope: &Scope) -> Result<Rc<Val>, Box<dyn Error>> {
|
||||
let v = self.eval_value(&def.selector, scope)?;
|
||||
if let &Val::Tuple(ref src_fields) = v.as_ref() {
|
||||
let child_scope = scope.spawn_child().set_curr_val(v.clone());
|
||||
return self.copy_from_base(&src_fields, &def.fields, &child_scope);
|
||||
}
|
||||
if let &Val::Module(ref mod_def) = v.as_ref() {
|
||||
return self.eval_module_copy(def, mod_def, scope);
|
||||
}
|
||||
Err(error::BuildError::with_pos(
|
||||
format!("Expected Tuple or Module but got ({})", v),
|
||||
error::ErrorType::TypeFail,
|
||||
|
@ -379,17 +379,28 @@ fn module_expression(input: SliceIter<Token>) -> Result<SliceIter<Token>, Expres
|
||||
_ => optional!(punct!(",")),
|
||||
_ => must!(punct!("}")),
|
||||
_ => must!(punct!("=>")),
|
||||
out_expr => optional!(
|
||||
do_each!(
|
||||
_ => punct!("("),
|
||||
expr => must!(expression),
|
||||
_ => must!(punct!(")")),
|
||||
(expr)
|
||||
)
|
||||
),
|
||||
_ => must!(punct!("{")),
|
||||
stmt_list => trace_parse!(repeat!(statement)),
|
||||
_ => must!(punct!("}")),
|
||||
(pos, arglist, stmt_list)
|
||||
(pos, arglist, out_expr, stmt_list)
|
||||
);
|
||||
match parsed {
|
||||
Result::Abort(e) => Result::Abort(e),
|
||||
Result::Fail(e) => Result::Fail(e),
|
||||
Result::Incomplete(offset) => Result::Incomplete(offset),
|
||||
Result::Complete(rest, (pos, arglist, stmt_list)) => {
|
||||
let def = ModuleDef::new(arglist.unwrap_or_else(|| Vec::new()), stmt_list, pos);
|
||||
Result::Complete(rest, (pos, arglist, out_expr, stmt_list)) => {
|
||||
let mut def = ModuleDef::new(arglist.unwrap_or_else(|| Vec::new()), stmt_list, pos);
|
||||
if let Some(expr) = out_expr {
|
||||
def.set_out_expr(expr);
|
||||
}
|
||||
//eprintln!(
|
||||
// "module def at: {:?} arg_typle len {} stmts len {}",
|
||||
// def.pos,
|
||||
|
Loading…
x
Reference in New Issue
Block a user