mirror of
https://github.com/tweag/nickel.git
synced 2024-09-11 11:47:03 +03:00
WIP
This commit is contained in:
parent
b3c8e30b68
commit
d9dcdb9b65
@ -2981,6 +2981,39 @@ impl<R: ImportResolver, C: Cache> VirtualMachine<R, C> {
|
||||
pos_op_inh,
|
||||
)))
|
||||
}
|
||||
BinaryOp::ContractBuiltin(builtin) => {
|
||||
let t1 = t1.into_owned();
|
||||
|
||||
let Term::Lbl(label) = t1 else {
|
||||
return mk_type_error!("Label", 1, t1.into(), pos1);
|
||||
};
|
||||
|
||||
match (&*t2, builtin) {
|
||||
(Term::Num(_), BuiltinContract::Number)
|
||||
| (Term::Str(_), BuiltinContract::String)
|
||||
| (Term::Bool(_), BuiltinContract::Bool)
|
||||
| (_, BuiltinContract::Dyn) => {
|
||||
let wrapped = Term::EnumVariant {
|
||||
tag: "Ok".into(),
|
||||
arg: RichTerm {
|
||||
term: t2,
|
||||
pos: pos2,
|
||||
},
|
||||
attrs: EnumVariantAttrs::new().closurized(),
|
||||
};
|
||||
|
||||
Ok(Closure {
|
||||
body: RichTerm::new(wrapped, pos2),
|
||||
env: env2,
|
||||
})
|
||||
}
|
||||
_ => Err(EvalError::BlameError {
|
||||
evaluated_arg: label.get_evaluated_arg(&self.cache),
|
||||
label,
|
||||
call_stack: std::mem::take(&mut self.call_stack),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1307,6 +1307,12 @@ BOpPre: BinaryOp = {
|
||||
"contract/check" => BinaryOp::ContractCheck,
|
||||
"contract/array_lazy_app" => BinaryOp::ContractArrayLazyApp,
|
||||
"contract/record_lazy_app" => BinaryOp::ContractRecordLazyApp,
|
||||
"contract/builtin/dyn" => BinaryOp::ContractBuiltin(BuiltinContract::Dyn),
|
||||
"contract/builtin/string" =>
|
||||
BinaryOp::ContractBuiltin(BuiltinContract::String),
|
||||
"contract/builtin/number" =>
|
||||
BinaryOp::ContractBuiltin(BuiltinContract::Number),
|
||||
"contract/builtin/bool" => BinaryOp::ContractBuiltin(BuiltinContract::Bool),
|
||||
"unseal" => BinaryOp::Unseal,
|
||||
"seal" => BinaryOp::Seal,
|
||||
"label/go_field" => BinaryOp::LabelGoField,
|
||||
@ -1529,6 +1535,10 @@ extern {
|
||||
"contract/array_lazy_app" => Token::Normal(NormalToken::ContractArrayLazyApp),
|
||||
"contract/record_lazy_app" => Token::Normal(NormalToken::ContractRecordLazyApp),
|
||||
"contract/custom" => Token::Normal(NormalToken::ContractCustom),
|
||||
"contract/builtin/dyn" => Token::Normal(NormalToken::ContractBuiltinDyn),
|
||||
"contract/builtin/string" => Token::Normal(NormalToken::ContractBuiltinString),
|
||||
"contract/builtin/bool" => Token::Normal(NormalToken::ContractBuiltinBool),
|
||||
"contract/builtin/number" => Token::Normal(NormalToken::ContractBuiltinNumber),
|
||||
"op force" => Token::Normal(NormalToken::OpForce),
|
||||
"blame" => Token::Normal(NormalToken::Blame),
|
||||
"label/flip_polarity" => Token::Normal(NormalToken::LabelFlipPol),
|
||||
|
@ -225,6 +225,15 @@ pub enum NormalToken<'input> {
|
||||
#[token("%label/lookup_type_variable%")]
|
||||
LabelLookupTypeVar,
|
||||
|
||||
#[token("%contract/builtin/dyn%")]
|
||||
ContractBuiltinDyn,
|
||||
#[token("%contract/builtin/number%")]
|
||||
ContractBuiltinNumber,
|
||||
#[token("%contract/builtin/string%")]
|
||||
ContractBuiltinString,
|
||||
#[token("%contract/builtin/bool%")]
|
||||
ContractBuiltinBool,
|
||||
|
||||
#[token("%seal%")]
|
||||
Seal,
|
||||
#[token("%unseal%")]
|
||||
|
@ -1682,6 +1682,14 @@ pub enum RecordOpKind {
|
||||
ConsiderAllFields,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum BuiltinContract {
|
||||
Bool,
|
||||
Number,
|
||||
Dyn,
|
||||
String,
|
||||
}
|
||||
|
||||
/// Primitive binary operators
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum BinaryOp {
|
||||
@ -1755,6 +1763,8 @@ pub enum BinaryOp {
|
||||
/// [Self::ContractCheck] preserves the immediate/delayed part of the called contract.
|
||||
ContractCheck,
|
||||
|
||||
ContractBuiltin(BuiltinContract),
|
||||
|
||||
/// Take a record of type `{message | String | optional, notes | String | optional}`.
|
||||
LabelWithErrorData,
|
||||
|
||||
@ -1909,6 +1919,10 @@ impl fmt::Display for BinaryOp {
|
||||
GreaterOrEq => write!(f, "(>=)"),
|
||||
ContractApply => write!(f, "contract/apply"),
|
||||
ContractCheck => write!(f, "contract/check"),
|
||||
ContractBuiltin(BuiltinContract::Dyn) => write!(f, "contract/builtin/dyn"),
|
||||
ContractBuiltin(BuiltinContract::Number) => write!(f, "contract/builtin/number"),
|
||||
ContractBuiltin(BuiltinContract::Bool) => write!(f, "contract/builtin/bool"),
|
||||
ContractBuiltin(BuiltinContract::String) => write!(f, "contract/builtin/string"),
|
||||
LabelWithErrorData => write!(f, "label/with_error_data"),
|
||||
Unseal => write!(f, "unseal"),
|
||||
LabelGoField => write!(f, "label/go_field"),
|
||||
|
@ -544,6 +544,12 @@ pub fn get_bop_type(
|
||||
|
||||
(dict.clone(), dict.clone(), dict)
|
||||
}
|
||||
// Dyn -> Dyn -> Dyn
|
||||
BinaryOp::ContractBuiltin(_) => (
|
||||
mk_uniftype::dynamic(),
|
||||
mk_uniftype::dynamic(),
|
||||
mk_uniftype::dynamic(),
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -9,28 +9,16 @@
|
||||
# |]` as well.
|
||||
|
||||
# Contract for the `Dyn` type. It's just an always accepting contract.
|
||||
"$dyn" = fun _label value => 'Ok value,
|
||||
"$dyn" = fun label value => %contract/builtin/dyn% label value,
|
||||
|
||||
# Contract for the `Number` type.
|
||||
"$num" = fun _label value =>
|
||||
if %typeof% value == 'Number then
|
||||
'Ok value
|
||||
else
|
||||
'Error {},
|
||||
"$num" = fun label value => %contract/builtin/number% label value,
|
||||
|
||||
# Contract for the `Bool` type.
|
||||
"$bool" = fun _label value =>
|
||||
if %typeof% value == 'Bool then
|
||||
'Ok value
|
||||
else
|
||||
'Error {},
|
||||
"$bool" = fun label value => %contract/builtin/bool% label value,
|
||||
|
||||
# Contract for the `String` type.
|
||||
"$string" = fun _label value =>
|
||||
if %typeof% value == 'String then
|
||||
'Ok value
|
||||
else
|
||||
'Error {},
|
||||
"$string" = fun label value => %contract/builtin/string% label value,
|
||||
|
||||
# Contract for `ForeignId` values.
|
||||
"$foreign_id" = fun _label value =>
|
||||
@ -379,7 +367,6 @@
|
||||
# just add the extra fields back to the returned value. See
|
||||
# `$record_type/delayed`.
|
||||
"$dyn_tail" = fun extra_fields label value => 'Ok (%record/disjoint_merge% value extra_fields),
|
||||
|
||||
# Tail wrapper of a helper for an empty tail. At this point, we've already
|
||||
# checked (in the main contract implementation for record types) that there
|
||||
# are no extra fields, so we can just ignore them and return the value as is.
|
||||
|
Loading…
Reference in New Issue
Block a user