1
0
Fork 0
mirror of synced 2025-09-23 12:18:44 +00:00

merge original alias branch

This commit is contained in:
schaeff 2021-09-21 18:02:21 +03:00
commit b38a9bc64e
19 changed files with 383 additions and 289 deletions

View file

@ -413,11 +413,8 @@ mod tests {
fn array() {
let s = "[[true, false]]";
assert_eq!(
parse_strict::<Bn128Field>(
s,
vec![ConcreteType::array((ConcreteType::Boolean, 2usize))]
)
.unwrap(),
parse_strict::<Bn128Field>(s, vec![ConcreteType::array((ConcreteType::Boolean, 2u32))])
.unwrap(),
Values(vec![Value::Array(vec![
Value::Boolean(true),
Value::Boolean(false)

View file

@ -247,6 +247,8 @@ fn check_with_arena<'ast, T: Field, E: Into<imports::Error>>(
let typed_ast = Checker::check(compiled)
.map_err(|errors| CompileErrors(errors.into_iter().map(CompileError::from).collect()))?;
log::trace!("\n{}", typed_ast);
let main_module = typed_ast.main.clone();
log::debug!("Run static analysis");

View file

@ -50,25 +50,16 @@ impl FlatEmbed {
match self {
FlatEmbed::BitArrayLe => DeclarationSignature::new()
.generics(vec![Some(DeclarationConstant::Generic(
GenericIdentifier {
name: "N",
index: 0,
},
GenericIdentifier::with_name("N").with_index(0),
))])
.inputs(vec![
DeclarationType::array((
DeclarationType::Boolean,
GenericIdentifier {
name: "N",
index: 0,
},
GenericIdentifier::with_name("N").with_index(0),
)),
DeclarationType::array((
DeclarationType::Boolean,
GenericIdentifier {
name: "N",
index: 0,
},
GenericIdentifier::with_name("N").with_index(0),
)),
])
.outputs(vec![DeclarationType::Boolean]),
@ -77,104 +68,90 @@ impl FlatEmbed {
.outputs(vec![DeclarationType::FieldElement]),
FlatEmbed::Unpack => DeclarationSignature::new()
.generics(vec![Some(DeclarationConstant::Generic(
GenericIdentifier {
name: "N",
index: 0,
},
GenericIdentifier::with_name("N").with_index(0),
))])
.inputs(vec![DeclarationType::FieldElement])
.outputs(vec![DeclarationType::array((
DeclarationType::Boolean,
GenericIdentifier {
name: "N",
index: 0,
},
GenericIdentifier::with_name("N").with_index(0),
))]),
FlatEmbed::U8ToBits => DeclarationSignature::new()
.inputs(vec![DeclarationType::uint(8)])
.outputs(vec![DeclarationType::array((
DeclarationType::Boolean,
8usize,
8u32,
))]),
FlatEmbed::U16ToBits => DeclarationSignature::new()
.inputs(vec![DeclarationType::uint(16)])
.outputs(vec![DeclarationType::array((
DeclarationType::Boolean,
16usize,
16u32,
))]),
FlatEmbed::U32ToBits => DeclarationSignature::new()
.inputs(vec![DeclarationType::uint(32)])
.outputs(vec![DeclarationType::array((
DeclarationType::Boolean,
32usize,
32u32,
))]),
FlatEmbed::U64ToBits => DeclarationSignature::new()
.inputs(vec![DeclarationType::uint(64)])
.outputs(vec![DeclarationType::array((
DeclarationType::Boolean,
64usize,
64u32,
))]),
FlatEmbed::U8FromBits => DeclarationSignature::new()
.outputs(vec![DeclarationType::uint(8)])
.inputs(vec![DeclarationType::array((
DeclarationType::Boolean,
8usize,
8u32,
))]),
FlatEmbed::U16FromBits => DeclarationSignature::new()
.outputs(vec![DeclarationType::uint(16)])
.inputs(vec![DeclarationType::array((
DeclarationType::Boolean,
16usize,
16u32,
))]),
FlatEmbed::U32FromBits => DeclarationSignature::new()
.outputs(vec![DeclarationType::uint(32)])
.inputs(vec![DeclarationType::array((
DeclarationType::Boolean,
32usize,
32u32,
))]),
FlatEmbed::U64FromBits => DeclarationSignature::new()
.outputs(vec![DeclarationType::uint(64)])
.inputs(vec![DeclarationType::array((
DeclarationType::Boolean,
64usize,
64u32,
))]),
#[cfg(feature = "bellman")]
FlatEmbed::Sha256Round => DeclarationSignature::new()
.inputs(vec![
DeclarationType::array((DeclarationType::Boolean, 512usize)),
DeclarationType::array((DeclarationType::Boolean, 256usize)),
DeclarationType::array((DeclarationType::Boolean, 512u32)),
DeclarationType::array((DeclarationType::Boolean, 256u32)),
])
.outputs(vec![DeclarationType::array((
DeclarationType::Boolean,
256usize,
256u32,
))]),
#[cfg(feature = "ark")]
FlatEmbed::SnarkVerifyBls12377 => DeclarationSignature::new()
.generics(vec![
Some(DeclarationConstant::Generic(GenericIdentifier {
name: "N",
index: 0,
})),
Some(DeclarationConstant::Generic(GenericIdentifier {
name: "V",
index: 1,
})),
Some(DeclarationConstant::Generic(
GenericIdentifier::with_name("N").with_index(0),
)),
Some(DeclarationConstant::Generic(
GenericIdentifier::with_name("V").with_index(1),
)),
])
.inputs(vec![
DeclarationType::array((
DeclarationType::FieldElement,
GenericIdentifier {
name: "N",
index: 0,
},
GenericIdentifier::with_name("N").with_index(0),
)), // inputs
DeclarationType::array((DeclarationType::FieldElement, 8usize)), // proof
DeclarationType::array((DeclarationType::FieldElement, 8u32)), // proof
DeclarationType::array((
DeclarationType::FieldElement,
GenericIdentifier {
name: "V",
index: 1,
},
GenericIdentifier::with_name("V").with_index(1),
)), // 18 + (2 * n) // vk
])
.outputs(vec![DeclarationType::Boolean]),

View file

@ -6,7 +6,7 @@
use crate::absy::Identifier;
use crate::absy::*;
use crate::typed_absy::types::{try_from_g_type, GGenericsAssignment};
use crate::typed_absy::types::{try_from_g_type, GGenericsAssignment, GenericsAssignment};
use crate::typed_absy::*;
use crate::typed_absy::{DeclarationParameter, DeclarationVariable, Variable};
use num_bigint::BigUint;
@ -55,7 +55,7 @@ impl ErrorInner {
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
enum TypeKind<'ast> {
Canonical(DeclarationType<'ast>),
Alias(
@ -396,10 +396,9 @@ impl<'ast, T: Field> Checker<'ast, T> {
} else {
match generics_map.insert(g.value, index).is_none() {
true => {
generics.push(Some(DeclarationConstant::Generic(GenericIdentifier {
name: g.value,
index,
})));
generics.push(Some(DeclarationConstant::Generic(
GenericIdentifier::with_name(g.value).with_index(index),
)));
}
false => {
errors.push(ErrorInner {
@ -529,10 +528,9 @@ impl<'ast, T: Field> Checker<'ast, T> {
} else {
match generics_map.insert(g.value, index).is_none() {
true => {
generics.push(Some(DeclarationConstant::Generic(GenericIdentifier {
name: g.value,
index,
})));
generics.push(Some(DeclarationConstant::Generic(
GenericIdentifier::with_name(g.value).with_index(index),
)));
}
false => {
errors.push(ErrorInner {
@ -1050,17 +1048,26 @@ impl<'ast, T: Field> Checker<'ast, T> {
match self.check_signature(funct.signature, module_id, state) {
Ok(s) => {
// initialise generics map
let mut generics: GenericsAssignment<'ast, T> = GGenericsAssignment::default();
// define variables for the constants
for generic in &s.generics {
let generic = generic.clone().unwrap(); // for declaration signatures, generics cannot be ignored
let generic = match generic.clone().unwrap() {
DeclarationConstant::Generic(g) => g,
_ => unreachable!(),
};
let v = Variable::with_id_and_type(
match generic {
DeclarationConstant::Generic(g) => g.name,
_ => unreachable!(),
},
Type::Uint(UBitwidth::B32),
// for declaration signatures, generics cannot be ignored
let v = Variable::with_id_and_type(generic.name(), Type::Uint(UBitwidth::B32));
generics.0.insert(
generic.clone(),
UExpressionInner::Identifier(generic.name().into())
.annotate(UBitwidth::B32),
);
// we don't have to check for conflicts here, because this was done when checking the signature
self.insert_into_scope(v.clone());
}
@ -1073,9 +1080,12 @@ impl<'ast, T: Field> Checker<'ast, T> {
let decl_v =
DeclarationVariable::with_id_and_type(arg.id.value.id, decl_ty.clone());
match self.insert_into_scope(
crate::typed_absy::variable::try_from_g_variable(decl_v.clone()).unwrap(),
) {
let ty = specialize_declaration_type(decl_v.clone()._type, &generics).unwrap();
match self.insert_into_scope(crate::typed_absy::variable::Variable {
id: decl_v.clone().id,
_type: ty,
}) {
true => {}
false => {
errors.push(ErrorInner {
@ -1198,10 +1208,9 @@ impl<'ast, T: Field> Checker<'ast, T> {
} else {
match generics_map.insert(g.value, index).is_none() {
true => {
generics.push(Some(DeclarationConstant::Generic(GenericIdentifier {
name: g.value,
index,
})));
generics.push(Some(DeclarationConstant::Generic(
GenericIdentifier::with_name(g.value).with_index(index),
)));
}
false => {
errors.push(ErrorInner {
@ -1470,7 +1479,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
})
}
}
(None, Some(index)) => Ok(DeclarationConstant::Generic(GenericIdentifier { name, index: *index })),
(None, Some(index)) => Ok(DeclarationConstant::Generic(GenericIdentifier::with_name(name).with_index(*index))),
_ => Err(ErrorInner {
pos: Some(pos),
message: format!("Undeclared symbol `{}`", name)
@ -1567,24 +1576,9 @@ impl<'ast, T: Field> Checker<'ast, T> {
}),
);
// generate actual type based on generic type and concrete generics
let members = declared_struct_ty
.members
.into_iter()
.map(|m| {
Ok(DeclarationStructMember {
ty: box specialize_declaration_type(*m.ty, &assignment)
.unwrap(),
..m
})
})
.collect::<Result<Vec<_>, _>>()?;
Ok(DeclarationType::Struct(DeclarationStructType {
canonical_location: declared_struct_ty.canonical_location,
location: declared_struct_ty.location,
generics: checked_generics,
members,
..declared_struct_ty
}))
}
false => Err(ErrorInner {
@ -3110,12 +3104,20 @@ impl<'ast, T: Field> Checker<'ast, T> {
Some(ty) => Ok(ty),
}?;
let declared_struct_type = match ty {
let mut declared_struct_type = match ty {
TypeKind::Canonical(DeclarationType::Struct(struct_type))
| TypeKind::Alias(DeclarationType::Struct(struct_type), _) => struct_type,
_ => unreachable!(),
};
declared_struct_type.generics = (0..declared_struct_type.generics.len())
.map(|index| {
Some(DeclarationConstant::Generic(
GenericIdentifier::without_name().with_index(index),
))
})
.collect();
// check that we provided the required number of values
if declared_struct_type.members_count() != inline_members.len() {
return Err(ErrorInner {
@ -3670,7 +3672,7 @@ mod tests {
"bar",
DeclarationSignature::new()
.generics(vec![Some(
GenericIdentifier::with_name("K").index(0).into()
GenericIdentifier::with_name("K").with_index(0).into()
)])
.inputs(vec![DeclarationType::FieldElement])
));
@ -3679,11 +3681,11 @@ mod tests {
"bar",
DeclarationSignature::new()
.generics(vec![Some(
GenericIdentifier::with_name("K").index(0).into()
GenericIdentifier::with_name("K").with_index(0).into()
)])
.inputs(vec![DeclarationType::array((
DeclarationType::FieldElement,
GenericIdentifier::with_name("K").index(0)
GenericIdentifier::with_name("K").with_index(0)
))])
));
// a `bar` function with an equivalent signature, just renaming generic parameters
@ -3691,11 +3693,11 @@ mod tests {
"bar",
DeclarationSignature::new()
.generics(vec![Some(
GenericIdentifier::with_name("L").index(0).into()
GenericIdentifier::with_name("L").with_index(0).into()
)])
.inputs(vec![DeclarationType::array((
DeclarationType::FieldElement,
GenericIdentifier::with_name("L").index(0)
GenericIdentifier::with_name("L").with_index(0)
))])
));
// a `bar` type isn't allowed as the name is already taken by at least one function
@ -4259,16 +4261,16 @@ mod tests {
.inputs(vec![DeclarationType::array((
DeclarationType::array((
DeclarationType::FieldElement,
GenericIdentifier::with_name("K").index(0)
GenericIdentifier::with_name("K").with_index(0)
)),
GenericIdentifier::with_name("L").index(1)
GenericIdentifier::with_name("L").with_index(1)
))])
.outputs(vec![DeclarationType::array((
DeclarationType::array((
DeclarationType::FieldElement,
GenericIdentifier::with_name("L").index(1)
GenericIdentifier::with_name("L").with_index(1)
)),
GenericIdentifier::with_name("K").index(0)
GenericIdentifier::with_name("K").with_index(0)
))]))
);
}
@ -5677,9 +5679,8 @@ mod tests {
.get(&*MODULE_ID)
.unwrap()
.get(&"Bar".to_string())
.map(|(ty, _)| ty)
.unwrap(),
&DeclarationType::Struct(DeclarationStructType::new(
&TypeKind::Canonical(DeclarationType::Struct(DeclarationStructType::new(
(*MODULE_ID).clone(),
"Bar".into(),
vec![],
@ -5695,7 +5696,7 @@ mod tests {
)]
))
)]
))
)))
);
}

View file

@ -574,13 +574,13 @@ mod tests {
statements: vec![TypedStatement::Return(vec![FieldElementExpression::Add(
FieldElementExpression::select(
ArrayExpressionInner::Identifier(Identifier::from(const_id))
.annotate(GType::FieldElement, 2usize),
.annotate(GType::FieldElement, 2u32),
UExpressionInner::Value(0u128).annotate(UBitwidth::B32),
)
.into(),
FieldElementExpression::select(
ArrayExpressionInner::Identifier(Identifier::from(const_id))
.annotate(GType::FieldElement, 2usize),
.annotate(GType::FieldElement, 2u32),
UExpressionInner::Value(1u128).annotate(UBitwidth::B32),
)
.into(),
@ -608,7 +608,7 @@ mod tests {
]
.into(),
)
.annotate(GType::FieldElement, 2usize),
.annotate(GType::FieldElement, 2u32),
))),
)]
.into_iter()
@ -649,7 +649,7 @@ mod tests {
]
.into(),
)
.annotate(GType::FieldElement, 2usize),
.annotate(GType::FieldElement, 2u32),
UExpressionInner::Value(0u128).annotate(UBitwidth::B32),
)
.into(),
@ -661,7 +661,7 @@ mod tests {
]
.into(),
)
.annotate(GType::FieldElement, 2usize),
.annotate(GType::FieldElement, 2u32),
UExpressionInner::Value(1u128).annotate(UBitwidth::B32),
)
.into(),

View file

@ -340,7 +340,7 @@ impl<'ast, T: Field> Flattener<T> {
&mut self,
statements_buffer: &mut Vec<zir::ZirStatement<'ast, T>>,
ty: &typed_absy::types::ConcreteType,
size: usize,
size: u32,
e: typed_absy::ArrayExpressionInner<'ast, T>,
) -> Vec<zir::ZirExpression<'ast, T>> {
fold_array_expression_inner(self, statements_buffer, ty, size, e)
@ -404,7 +404,7 @@ fn fold_array_expression_inner<'ast, T: Field>(
f: &mut Flattener<T>,
statements_buffer: &mut Vec<zir::ZirStatement<'ast, T>>,
ty: &typed_absy::types::ConcreteType,
size: usize,
size: u32,
array: typed_absy::ArrayExpressionInner<'ast, T>,
) -> Vec<zir::ZirExpression<'ast, T>> {
match array {
@ -437,7 +437,7 @@ fn fold_array_expression_inner<'ast, T: Field>(
.flat_map(|e| f.fold_expression_or_spread(statements_buffer, e))
.collect();
assert_eq!(exprs.len(), size * ty.get_primitive_count());
assert_eq!(exprs.len(), size as usize * ty.get_primitive_count());
exprs
}
@ -458,7 +458,7 @@ fn fold_array_expression_inner<'ast, T: Field>(
match (from.into_inner(), to.into_inner()) {
(zir::UExpressionInner::Value(from), zir::UExpressionInner::Value(to)) => {
assert_eq!(size, to.saturating_sub(from) as usize);
assert_eq!(size, to.saturating_sub(from) as u32);
let element_size = ty.get_primitive_count();
let start = from as usize * element_size;
@ -1108,10 +1108,7 @@ fn fold_array_expression<'ast, T: Field>(
statements_buffer: &mut Vec<zir::ZirStatement<'ast, T>>,
e: typed_absy::ArrayExpression<'ast, T>,
) -> Vec<zir::ZirExpression<'ast, T>> {
let size = match e.size().into_inner() {
typed_absy::UExpressionInner::Value(v) => v,
_ => unreachable!(),
} as usize;
let size: u32 = e.size().try_into().unwrap();
f.fold_array_expression_inner(
statements_buffer,
&typed_absy::types::ConcreteType::try_from(e.inner_type().clone()).unwrap(),

View file

@ -11,6 +11,7 @@ mod flat_propagation;
mod flatten_complex_types;
mod propagation;
mod reducer;
mod struct_concretizer;
mod uint_optimizer;
mod unconstrained_vars;
mod variable_write_remover;
@ -20,6 +21,7 @@ use self::constant_argument_checker::ConstantArgumentChecker;
use self::flatten_complex_types::Flattener;
use self::propagation::Propagator;
use self::reducer::reduce_program;
use self::struct_concretizer::StructConcretizer;
use self::uint_optimizer::UintOptimizer;
use self::unconstrained_vars::UnconstrainedVariableDetector;
use self::variable_write_remover::VariableWriteRemover;
@ -101,6 +103,14 @@ impl<'ast, T: Field> TypedProgram<'ast, T> {
let r = reduce_program(r).map_err(Error::from)?;
log::trace!("\n{}", r);
log::debug!("Static analyser: Propagate");
let r = Propagator::propagate(r)?;
log::trace!("\n{}", r);
log::debug!("Static analyser: Concretize structs");
let r = StructConcretizer::concretize(r);
log::trace!("\n{}", r);
// generate abi
log::debug!("Static analyser: Generate abi");
let abi = r.abi();

View file

@ -1194,16 +1194,14 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
let e1 = self.fold_struct_expression(e1)?;
let e2 = self.fold_struct_expression(e2)?;
if let (Ok(t1), Ok(t2)) = (
ConcreteType::try_from(e1.get_type()),
ConcreteType::try_from(e2.get_type()),
) {
if t1 != t2 {
return Err(Error::Type(format!(
"Cannot compare {} of type {} to {} of type {}",
e1, t1, e2, t2
)));
}
let t1 = e1.get_type();
let t2 = e2.get_type();
if t1 != t2 {
return Err(Error::Type(format!(
"Cannot compare {} of type {} to {} of type {}",
e1, t1, e2, t2
)));
};
Ok(BooleanExpression::StructEq(box e1, box e2))
@ -1465,7 +1463,7 @@ mod tests {
]
.into(),
)
.annotate(Type::FieldElement, 3usize),
.annotate(Type::FieldElement, 3u32),
UExpressionInner::Add(box 1u32.into(), box 1u32.into())
.annotate(UBitwidth::B32),
);

View file

@ -830,22 +830,22 @@ mod tests {
let foo_signature = DeclarationSignature::new()
.generics(vec![Some(
GenericIdentifier::with_name("K").index(0).into(),
GenericIdentifier::with_name("K").with_index(0).into(),
)])
.inputs(vec![DeclarationType::array((
DeclarationType::FieldElement,
DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)),
DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)),
))])
.outputs(vec![DeclarationType::array((
DeclarationType::FieldElement,
DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)),
DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)),
))]);
let foo: TypedFunction<Bn128Field> = TypedFunction {
arguments: vec![DeclarationVariable::array(
"a",
DeclarationType::FieldElement,
GenericIdentifier::with_name("K").index(0),
GenericIdentifier::with_name("K").with_index(0),
)
.into()],
statements: vec![TypedStatement::Return(vec![
@ -954,7 +954,7 @@ mod tests {
DeclarationFunctionKey::with_location("main", "foo")
.signature(foo_signature.clone()),
GGenericsAssignment(
vec![(GenericIdentifier::with_name("K").index(0), 1)]
vec![(GenericIdentifier::with_name("K").with_index(0), 1)]
.into_iter()
.collect(),
),
@ -1049,22 +1049,22 @@ mod tests {
let foo_signature = DeclarationSignature::new()
.generics(vec![Some(
GenericIdentifier::with_name("K").index(0).into(),
GenericIdentifier::with_name("K").with_index(0).into(),
)])
.inputs(vec![DeclarationType::array((
DeclarationType::FieldElement,
DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)),
DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)),
))])
.outputs(vec![DeclarationType::array((
DeclarationType::FieldElement,
DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)),
DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)),
))]);
let foo: TypedFunction<Bn128Field> = TypedFunction {
arguments: vec![DeclarationVariable::array(
"a",
DeclarationType::FieldElement,
GenericIdentifier::with_name("K").index(0),
GenericIdentifier::with_name("K").with_index(0),
)
.into()],
statements: vec![TypedStatement::Return(vec![
@ -1182,7 +1182,7 @@ mod tests {
DeclarationFunctionKey::with_location("main", "foo")
.signature(foo_signature.clone()),
GGenericsAssignment(
vec![(GenericIdentifier::with_name("K").index(0), 1)]
vec![(GenericIdentifier::with_name("K").with_index(0), 1)]
.into_iter()
.collect(),
),
@ -1280,21 +1280,21 @@ mod tests {
let foo_signature = DeclarationSignature::new()
.inputs(vec![DeclarationType::array((
DeclarationType::FieldElement,
DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)),
DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)),
))])
.outputs(vec![DeclarationType::array((
DeclarationType::FieldElement,
DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)),
DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)),
))])
.generics(vec![Some(
GenericIdentifier::with_name("K").index(0).into(),
GenericIdentifier::with_name("K").with_index(0).into(),
)]);
let foo: TypedFunction<Bn128Field> = TypedFunction {
arguments: vec![DeclarationVariable::array(
"a",
DeclarationType::FieldElement,
DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)),
DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)),
)
.into()],
statements: vec![
@ -1358,7 +1358,7 @@ mod tests {
arguments: vec![DeclarationVariable::array(
"a",
DeclarationType::FieldElement,
DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)),
DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)),
)
.into()],
statements: vec![TypedStatement::Return(vec![
@ -1433,7 +1433,7 @@ mod tests {
DeclarationFunctionKey::with_location("main", "foo")
.signature(foo_signature.clone()),
GGenericsAssignment(
vec![(GenericIdentifier::with_name("K").index(0), 1)]
vec![(GenericIdentifier::with_name("K").with_index(0), 1)]
.into_iter()
.collect(),
),
@ -1442,7 +1442,7 @@ mod tests {
DeclarationFunctionKey::with_location("main", "bar")
.signature(foo_signature.clone()),
GGenericsAssignment(
vec![(GenericIdentifier::with_name("K").index(0), 2)]
vec![(GenericIdentifier::with_name("K").with_index(0), 2)]
.into_iter()
.collect(),
),
@ -1489,22 +1489,22 @@ mod tests {
let foo_signature = DeclarationSignature::new()
.generics(vec![Some(
GenericIdentifier::with_name("K").index(0).into(),
GenericIdentifier::with_name("K").with_index(0).into(),
)])
.inputs(vec![DeclarationType::array((
DeclarationType::FieldElement,
GenericIdentifier::with_name("K").index(0),
GenericIdentifier::with_name("K").with_index(0),
))])
.outputs(vec![DeclarationType::array((
DeclarationType::FieldElement,
GenericIdentifier::with_name("K").index(0),
GenericIdentifier::with_name("K").with_index(0),
))]);
let foo: TypedFunction<Bn128Field> = TypedFunction {
arguments: vec![DeclarationVariable::array(
"a",
DeclarationType::FieldElement,
GenericIdentifier::with_name("K").index(0),
GenericIdentifier::with_name("K").with_index(0),
)
.into()],
statements: vec![TypedStatement::Return(vec![

View file

@ -105,7 +105,7 @@ impl<'ast, 'a> ShallowTransformer<'ast, 'a> {
.map(|(g, v)| {
TypedStatement::Definition(
TypedAssignee::Identifier(Variable::with_id_and_type(
g.name,
g.name(),
Type::Uint(UBitwidth::B32),
)),
UExpression::from(*v as u32).into(),
@ -662,7 +662,7 @@ mod tests {
],
signature: DeclarationSignature::new()
.generics(vec![Some(
GenericIdentifier::with_name("K").index(0).into(),
GenericIdentifier::with_name("K").with_index(0).into(),
)])
.inputs(vec![DeclarationType::FieldElement])
.outputs(vec![DeclarationType::FieldElement]),
@ -673,7 +673,7 @@ mod tests {
let ssa = ShallowTransformer::transform(
f,
&GGenericsAssignment(
vec![(GenericIdentifier::with_name("K").index(0), 1)]
vec![(GenericIdentifier::with_name("K").with_index(0), 1)]
.into_iter()
.collect(),
),
@ -742,7 +742,7 @@ mod tests {
],
signature: DeclarationSignature::new()
.generics(vec![Some(
GenericIdentifier::with_name("K").index(0).into(),
GenericIdentifier::with_name("K").with_index(0).into(),
)])
.inputs(vec![DeclarationType::FieldElement])
.outputs(vec![DeclarationType::FieldElement]),
@ -851,7 +851,7 @@ mod tests {
],
signature: DeclarationSignature::new()
.generics(vec![Some(
GenericIdentifier::with_name("K").index(0).into(),
GenericIdentifier::with_name("K").with_index(0).into(),
)])
.inputs(vec![DeclarationType::FieldElement])
.outputs(vec![DeclarationType::FieldElement]),
@ -862,7 +862,7 @@ mod tests {
let ssa = ShallowTransformer::transform(
f,
&GGenericsAssignment(
vec![(GenericIdentifier::with_name("K").index(0), 1)]
vec![(GenericIdentifier::with_name("K").with_index(0), 1)]
.into_iter()
.collect(),
),
@ -934,7 +934,7 @@ mod tests {
],
signature: DeclarationSignature::new()
.generics(vec![Some(
GenericIdentifier::with_name("K").index(0).into(),
GenericIdentifier::with_name("K").with_index(0).into(),
)])
.inputs(vec![DeclarationType::FieldElement])
.outputs(vec![DeclarationType::FieldElement]),

View file

@ -0,0 +1,91 @@
// After all generics are inlined, a program should be completely "concrete", which means that all types must only contain
// litterals for array sizes. This is especially important to generate the ABI of the program.
// It is direct to ensure that with most types, however the way structs are implemented requires a slightly different process:
// Where for an array, `field[N]` ends up being propagated to `field[42]` which is direct to turn into a concrete type,
// for structs, `Foo<N> { field[N] a }` is propagated to `Foo<42> { field[N] a }`. The missing step is replacing `N` by `42`
// *inside* the canonical type, so that it can be concretized in the same way arrays are.
// We apply this transformation only to the main function.
use crate::typed_absy::folder::*;
use crate::typed_absy::{
types::{
ConcreteGenericsAssignment, DeclarationArrayType, DeclarationConstant,
DeclarationStructMember, GGenericsAssignment,
},
DeclarationStructType, GenericIdentifier, TypedProgram,
};
use std::marker::PhantomData;
use zokrates_field::Field;
pub struct StructConcretizer<'ast, T> {
generics: ConcreteGenericsAssignment<'ast>,
marker: PhantomData<T>,
}
impl<'ast, T: Field> StructConcretizer<'ast, T> {
pub fn concretize(p: TypedProgram<'ast, T>) -> TypedProgram<'ast, T> {
StructConcretizer::with_generics(ConcreteGenericsAssignment::default()).fold_program(p)
}
pub fn with_generics(generics: ConcreteGenericsAssignment<'ast>) -> Self {
Self {
generics,
marker: PhantomData,
}
}
}
impl<'ast, T: Field> Folder<'ast, T> for StructConcretizer<'ast, T> {
fn fold_declaration_struct_type(
&mut self,
ty: DeclarationStructType<'ast>,
) -> DeclarationStructType<'ast> {
let concrete_generics: Vec<u32> = ty
.generics
.clone()
.into_iter()
.map(|g| g.unwrap().map_concrete(&self.generics).unwrap())
.collect();
let concrete_generics_map: ConcreteGenericsAssignment = GGenericsAssignment(
concrete_generics
.iter()
.enumerate()
.map(|(index, g)| (GenericIdentifier::without_name().with_index(index), *g))
.collect(),
);
let mut internal_concretizer: StructConcretizer<'ast, T> =
StructConcretizer::with_generics(concrete_generics_map);
DeclarationStructType {
members: ty
.members
.into_iter()
.map(|member| {
DeclarationStructMember::new(
member.id,
internal_concretizer.fold_declaration_type(*member.ty),
)
})
.collect(),
generics: concrete_generics
.into_iter()
.map(|g| Some(DeclarationConstant::Concrete(g as u32)))
.collect(),
..ty
}
}
fn fold_declaration_array_type(
&mut self,
ty: DeclarationArrayType<'ast>,
) -> DeclarationArrayType<'ast> {
let size = ty.size.map_concrete(&self.generics).unwrap();
DeclarationArrayType {
size: DeclarationConstant::Concrete(size),
ty: box self.fold_declaration_type(*ty.ty),
}
}
}

View file

@ -37,10 +37,9 @@ impl<'ast> VariableWriteRemover {
let inner_ty = base.inner_type();
let size = base.size();
let size = match size.as_inner() {
UExpressionInner::Value(v) => *v as u32,
_ => unreachable!(),
};
use std::convert::TryInto;
let size: u32 = size.try_into().unwrap();
let head = indices.remove(0);
let tail = indices;

View file

@ -231,12 +231,12 @@ mod tests {
ty: ConcreteType::Struct(ConcreteStructType::new(
"".into(),
"Bar".into(),
vec![Some(1usize)],
vec![Some(1u32)],
vec![ConcreteStructMember::new(
String::from("a"),
ConcreteType::Array(ConcreteArrayType::new(
ConcreteType::FieldElement,
1usize,
1u32,
)),
)],
)),
@ -400,7 +400,7 @@ mod tests {
ConcreteStructMember::new(String::from("c"), ConcreteType::Boolean),
],
)),
2usize,
2u32,
)),
}],
outputs: vec![ConcreteType::Boolean],
@ -454,8 +454,8 @@ mod tests {
name: String::from("a"),
public: false,
ty: ConcreteType::Array(ConcreteArrayType::new(
ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 2usize)),
2usize,
ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 2u32)),
2u32,
)),
}],
outputs: vec![ConcreteType::FieldElement],

View file

@ -57,21 +57,39 @@ impl<'ast, T> Types<'ast, T> {
}
}
#[derive(Debug, Clone, Eq, Ord)]
#[derive(Debug, Clone, Eq)]
pub struct GenericIdentifier<'ast> {
pub name: &'ast str,
pub index: usize,
name: Option<&'ast str>,
index: usize,
}
impl<'ast> GenericIdentifier<'ast> {
pub fn with_name(name: &'ast str) -> Self {
Self { name, index: 0 }
pub fn without_name() -> Self {
Self {
name: None,
index: 0,
}
}
pub fn index(mut self, index: usize) -> Self {
pub fn with_name(name: &'ast str) -> Self {
Self {
name: Some(name),
index: 0,
}
}
pub fn with_index(mut self, index: usize) -> Self {
self.index = index;
self
}
pub fn name(&self) -> &'ast str {
self.name.unwrap()
}
pub fn index(&self) -> usize {
self.index
}
}
impl<'ast> PartialEq for GenericIdentifier<'ast> {
@ -86,6 +104,12 @@ impl<'ast> PartialOrd for GenericIdentifier<'ast> {
}
}
impl<'ast> Ord for GenericIdentifier<'ast> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.partial_cmp(other).unwrap()
}
}
impl<'ast> Hash for GenericIdentifier<'ast> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.index.hash(state);
@ -94,7 +118,7 @@ impl<'ast> Hash for GenericIdentifier<'ast> {
impl<'ast> fmt::Display for GenericIdentifier<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name)
write!(f, "{}", self.name())
}
}
@ -131,6 +155,32 @@ pub enum DeclarationConstant<'ast> {
Constant(CanonicalConstantIdentifier<'ast>),
}
impl<'ast> DeclarationConstant<'ast> {
pub fn map<S: From<CanonicalConstantIdentifier<'ast>> + From<u32> + Clone>(
self,
generics: &GGenericsAssignment<'ast, S>,
) -> Result<S, GenericIdentifier<'ast>> {
match self {
DeclarationConstant::Generic(g) => generics.0.get(&g).cloned().ok_or(g),
DeclarationConstant::Concrete(v) => Ok(v.into()),
DeclarationConstant::Constant(c) => Ok(c.into()),
}
}
pub fn map_concrete<S: From<u32> + Clone>(
self,
generics: &GGenericsAssignment<'ast, S>,
) -> Result<S, GenericIdentifier<'ast>> {
match self {
DeclarationConstant::Constant(_) => unreachable!(
"called map_concrete on a constant, it should have been resolved before"
),
DeclarationConstant::Generic(g) => generics.0.get(&g).cloned().ok_or(g),
DeclarationConstant::Concrete(v) => Ok(v.into()),
}
}
}
impl<'ast, T> PartialEq<UExpression<'ast, T>> for DeclarationConstant<'ast> {
fn eq(&self, other: &UExpression<'ast, T>) -> bool {
match (self, other.as_inner()) {
@ -152,12 +202,6 @@ impl<'ast> From<u32> for DeclarationConstant<'ast> {
}
}
impl<'ast> From<usize> for DeclarationConstant<'ast> {
fn from(e: usize) -> Self {
DeclarationConstant::Concrete(e as u32)
}
}
impl<'ast> From<GenericIdentifier<'ast>> for DeclarationConstant<'ast> {
fn from(e: GenericIdentifier<'ast>) -> Self {
DeclarationConstant::Generic(e)
@ -174,8 +218,8 @@ impl<'ast> fmt::Display for DeclarationConstant<'ast> {
}
}
impl<'ast, T> From<usize> for UExpression<'ast, T> {
fn from(i: usize) -> Self {
impl<'ast, T> From<u32> for UExpression<'ast, T> {
fn from(i: u32) -> Self {
UExpressionInner::Value(i as u128).annotate(UBitwidth::B32)
}
}
@ -184,7 +228,7 @@ impl<'ast, T> From<DeclarationConstant<'ast>> for UExpression<'ast, T> {
fn from(c: DeclarationConstant<'ast>) -> Self {
match c {
DeclarationConstant::Generic(i) => {
UExpressionInner::Identifier(i.name.into()).annotate(UBitwidth::B32)
UExpressionInner::Identifier(i.name().into()).annotate(UBitwidth::B32)
}
DeclarationConstant::Concrete(v) => {
UExpressionInner::Value(v as u128).annotate(UBitwidth::B32)
@ -196,25 +240,14 @@ impl<'ast, T> From<DeclarationConstant<'ast>> for UExpression<'ast, T> {
}
}
impl<'ast, T> TryInto<usize> for UExpression<'ast, T> {
impl<'ast, T> TryInto<u32> for UExpression<'ast, T> {
type Error = SpecializationError;
fn try_into(self) -> Result<usize, Self::Error> {
fn try_into(self) -> Result<u32, Self::Error> {
assert_eq!(self.bitwidth, UBitwidth::B32);
match self.into_inner() {
UExpressionInner::Value(v) => Ok(v as usize),
_ => Err(SpecializationError),
}
}
}
impl<'ast> TryInto<usize> for DeclarationConstant<'ast> {
type Error = SpecializationError;
fn try_into(self) -> Result<usize, Self::Error> {
match self {
DeclarationConstant::Concrete(v) => Ok(v as usize),
UExpressionInner::Value(v) => Ok(v as u32),
_ => Err(SpecializationError),
}
}
@ -231,7 +264,7 @@ pub struct GStructMember<S> {
}
pub type DeclarationStructMember<'ast> = GStructMember<DeclarationConstant<'ast>>;
pub type ConcreteStructMember = GStructMember<usize>;
pub type ConcreteStructMember = GStructMember<u32>;
pub type StructMember<'ast, T> = GStructMember<UExpression<'ast, T>>;
impl<'ast, S, R: PartialEq<S>> PartialEq<GStructMember<S>> for GStructMember<R> {
@ -271,7 +304,7 @@ pub struct GArrayType<S> {
}
pub type DeclarationArrayType<'ast> = GArrayType<DeclarationConstant<'ast>>;
pub type ConcreteArrayType = GArrayType<usize>;
pub type ConcreteArrayType = GArrayType<u32>;
pub type ArrayType<'ast, T> = GArrayType<UExpression<'ast, T>>;
impl<'ast, S, R: PartialEq<S>> PartialEq<GArrayType<S>> for GArrayType<R> {
@ -353,7 +386,7 @@ pub struct GStructType<S> {
}
pub type DeclarationStructType<'ast> = GStructType<DeclarationConstant<'ast>>;
pub type ConcreteStructType = GStructType<usize>;
pub type ConcreteStructType = GStructType<u32>;
pub type StructType<'ast, T> = GStructType<UExpression<'ast, T>>;
impl<'ast, S, R: PartialEq<S>> PartialEq<GStructType<S>> for GStructType<R> {
@ -365,8 +398,7 @@ impl<'ast, S, R: PartialEq<S>> PartialEq<GStructType<S>> for GStructType<R> {
.zip(other.generics.iter())
.all(|(a, b)| match (a, b) {
(Some(a), Some(b)) => a == b,
(None, None) => true,
_ => false,
_ => true,
})
}
}
@ -610,7 +642,7 @@ impl<'de, S: Deserialize<'de>> Deserialize<'de> for GType<S> {
}
pub type DeclarationType<'ast> = GType<DeclarationConstant<'ast>>;
pub type ConcreteType = GType<usize>;
pub type ConcreteType = GType<u32>;
pub type Type<'ast, T> = GType<UExpression<'ast, T>>;
impl<'ast, S, R: PartialEq<S>> PartialEq<GType<S>> for GType<R> {
@ -799,7 +831,9 @@ impl ConcreteType {
GType::FieldElement => 1,
GType::Boolean => 1,
GType::Uint(_) => 1,
GType::Array(array_type) => array_type.size * array_type.ty.get_primitive_count(),
GType::Array(array_type) => {
array_type.size as usize * array_type.ty.get_primitive_count()
}
GType::Int => unreachable!(),
GType::Struct(struct_type) => struct_type
.iter()
@ -819,7 +853,7 @@ pub struct GFunctionKey<'ast, S> {
}
pub type DeclarationFunctionKey<'ast> = GFunctionKey<'ast, DeclarationConstant<'ast>>;
pub type ConcreteFunctionKey<'ast> = GFunctionKey<'ast, usize>;
pub type ConcreteFunctionKey<'ast> = GFunctionKey<'ast, u32>;
pub type FunctionKey<'ast, T> = GFunctionKey<'ast, UExpression<'ast, T>>;
impl<'ast, S: fmt::Display> fmt::Display for GFunctionKey<'ast, S> {
@ -831,7 +865,7 @@ impl<'ast, S: fmt::Display> fmt::Display for GFunctionKey<'ast, S> {
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub struct GGenericsAssignment<'ast, S>(pub BTreeMap<GenericIdentifier<'ast>, S>);
pub type ConcreteGenericsAssignment<'ast> = GGenericsAssignment<'ast, usize>;
pub type ConcreteGenericsAssignment<'ast> = GGenericsAssignment<'ast, u32>;
pub type GenericsAssignment<'ast, T> = GGenericsAssignment<'ast, UExpression<'ast, T>>;
impl<'ast, S> Default for GGenericsAssignment<'ast, S> {
@ -931,7 +965,7 @@ impl<'ast> ConcreteFunctionKey<'ast> {
use std::collections::btree_map::Entry;
pub fn check_type<'ast, S: Clone + PartialEq + PartialEq<usize>>(
pub fn check_type<'ast, S: Clone + PartialEq + PartialEq<u32>>(
decl_ty: &DeclarationType<'ast>,
ty: &GType<S>,
constants: &mut GGenericsAssignment<'ast, S>,
@ -952,7 +986,7 @@ pub fn check_type<'ast, S: Clone + PartialEq + PartialEq<usize>>(
true
}
},
DeclarationConstant::Concrete(s0) => s1 == *s0 as usize,
DeclarationConstant::Concrete(s0) => s1 == *s0 as u32,
// in the case of a constant, we do not know the value yet, so we optimistically assume it's correct
// if it does not match, it will be caught during inlining
DeclarationConstant::Constant(..) => true,
@ -995,51 +1029,55 @@ pub fn specialize_declaration_type<
Ok(match decl_ty {
DeclarationType::Int => unreachable!(),
DeclarationType::Array(t0) => {
// let s1 = t1.size.clone();
let ty = box specialize_declaration_type(*t0.ty, &generics)?;
let size = match t0.size {
DeclarationConstant::Generic(s) => generics.0.get(&s).cloned().ok_or(s),
DeclarationConstant::Concrete(s) => Ok(s.into()),
DeclarationConstant::Constant(c) => Ok(c.into()),
}?;
let size = t0.size.map(generics)?;
GType::Array(GArrayType { size, ty })
}
DeclarationType::FieldElement => GType::FieldElement,
DeclarationType::Boolean => GType::Boolean,
DeclarationType::Uint(b0) => GType::Uint(b0),
DeclarationType::Struct(s0) => GType::Struct(GStructType {
members: s0
.members
.into_iter()
.map(|m| {
let id = m.id;
specialize_declaration_type(*m.ty, generics)
.map(|ty| GStructMember { ty: box ty, id })
})
.collect::<Result<_, _>>()?,
generics: s0
.generics
.into_iter()
.map(|g| match g {
Some(constant) => match constant {
DeclarationConstant::Generic(s) => {
generics.0.get(&s).cloned().ok_or(s).map(Some)
}
DeclarationConstant::Concrete(s) => Ok(Some(s.into())),
DeclarationConstant::Constant(..) => {
unreachable!(
"identifiers should have been removed in constant inlining"
)
}
},
_ => Ok(None),
})
.collect::<Result<_, _>>()?,
canonical_location: s0.canonical_location,
location: s0.location,
}),
DeclarationType::Struct(s0) => {
// here we specialize Foo<Generics> {FooDef<InsideGenerics>} with some values for Generics
// we need to remap these values for InsideGenerics to then visit the members
let inside_generics = GGenericsAssignment(
s0.generics
.clone()
.into_iter()
.enumerate()
.map(|(index, g)| {
(
GenericIdentifier::without_name().with_index(index),
g.map(|g| g.map(generics).unwrap()).unwrap(),
)
})
.collect(),
);
GType::Struct(GStructType {
members: s0
.members
.into_iter()
.map(|m| {
let id = m.id;
specialize_declaration_type(*m.ty, &inside_generics)
.map(|ty| GStructMember { ty: box ty, id })
})
.collect::<Result<_, _>>()?,
generics: s0
.generics
.into_iter()
.map(|g| match g {
Some(constant) => constant.map(generics).map(Some),
_ => Ok(None),
})
.collect::<Result<_, _>>()?,
canonical_location: s0.canonical_location,
location: s0.location,
})
}
})
}
@ -1097,7 +1135,7 @@ pub mod signature {
}
pub type DeclarationSignature<'ast> = GSignature<DeclarationConstant<'ast>>;
pub type ConcreteSignature = GSignature<usize>;
pub type ConcreteSignature = GSignature<u32>;
pub type Signature<'ast, T> = GSignature<UExpression<'ast, T>>;
impl<'ast> PartialEq<DeclarationSignature<'ast>> for ConcreteSignature {
@ -1110,7 +1148,7 @@ pub mod signature {
.iter()
.chain(other.outputs.iter())
.zip(self.inputs.iter().chain(self.outputs.iter()))
.all(|(decl_ty, ty)| check_type::<usize>(decl_ty, ty, &mut constants))
.all(|(decl_ty, ty)| check_type::<u32>(decl_ty, ty, &mut constants))
}
}
@ -1135,7 +1173,7 @@ pub mod signature {
constants.0.extend(
decl_generics
.zip(values.into_iter())
.filter_map(|(g, v)| v.map(|v| (g, v as usize))),
.filter_map(|(g, v)| v.map(|v| (g, v))),
);
let condition = self
@ -1367,33 +1405,19 @@ pub mod signature {
let generic1 = DeclarationSignature::new()
.generics(vec![Some(
GenericIdentifier {
name: "P",
index: 0,
}
.into(),
GenericIdentifier::with_name("P").with_index(0).into(),
)])
.inputs(vec![DeclarationType::array(DeclarationArrayType::new(
DeclarationType::FieldElement,
GenericIdentifier {
name: "P",
index: 0,
},
GenericIdentifier::with_name("P").with_index(0),
))]);
let generic2 = DeclarationSignature::new()
.generics(vec![Some(
GenericIdentifier {
name: "Q",
index: 0,
}
.into(),
GenericIdentifier::with_name("Q").with_index(0).into(),
)])
.inputs(vec![DeclarationType::array(DeclarationArrayType::new(
DeclarationType::FieldElement,
GenericIdentifier {
name: "Q",
index: 0,
},
GenericIdentifier::with_name("Q").with_index(0),
))]);
assert_eq!(generic1, generic2);
@ -1458,8 +1482,8 @@ pub mod signature {
fn array_slug() {
let s = ConcreteSignature::new()
.inputs(vec![
ConcreteType::array((ConcreteType::FieldElement, 42usize)),
ConcreteType::array((ConcreteType::FieldElement, 21usize)),
ConcreteType::array((ConcreteType::FieldElement, 42u32)),
ConcreteType::array((ConcreteType::FieldElement, 21u32)),
])
.outputs(vec![]);
@ -1474,7 +1498,7 @@ mod tests {
#[test]
fn array() {
let t = ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 42usize));
let t = ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 42u32));
assert_eq!(t.get_primitive_count(), 42);
}
@ -1482,8 +1506,8 @@ mod tests {
fn array_display() {
// field[1][2]
let t = ConcreteType::Array(ConcreteArrayType::new(
ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 2usize)),
1usize,
ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 2u32)),
1u32,
));
assert_eq!(format!("{}", t), "field[1][2]");
}

View file

@ -146,12 +146,6 @@ pub struct UExpression<'ast, T> {
pub inner: UExpressionInner<'ast, T>,
}
impl<'ast, T> From<u32> for UExpression<'ast, T> {
fn from(u: u32) -> Self {
UExpressionInner::Value(u as u128).annotate(UBitwidth::B32)
}
}
impl<'ast, T> From<u16> for UExpression<'ast, T> {
fn from(u: u16) -> Self {
UExpressionInner::Value(u as u128).annotate(UBitwidth::B16)
@ -164,8 +158,8 @@ impl<'ast, T> From<u8> for UExpression<'ast, T> {
}
}
impl<'ast, T> PartialEq<usize> for UExpression<'ast, T> {
fn eq(&self, other: &usize) -> bool {
impl<'ast, T> PartialEq<u32> for UExpression<'ast, T> {
fn eq(&self, other: &u32) -> bool {
match self.as_inner() {
UExpressionInner::Value(v) => *v == *other as u128,
_ => true,

View file

@ -12,7 +12,7 @@ pub struct GVariable<'ast, S> {
}
pub type DeclarationVariable<'ast> = GVariable<'ast, DeclarationConstant<'ast>>;
pub type ConcreteVariable<'ast> = GVariable<'ast, usize>;
pub type ConcreteVariable<'ast> = GVariable<'ast, u32>;
pub type Variable<'ast, T> = GVariable<'ast, UExpression<'ast, T>>;
impl<'ast, T> TryFrom<Variable<'ast, T>> for ConcreteVariable<'ast> {

View file

@ -11,7 +11,7 @@ pub enum Identifier<'ast> {
#[derive(Debug, PartialEq, Clone, Hash, Eq)]
pub enum SourceIdentifier<'ast> {
Basic(CoreIdentifier<'ast>),
Select(Box<SourceIdentifier<'ast>>, usize),
Select(Box<SourceIdentifier<'ast>>, u32),
Member(Box<SourceIdentifier<'ast>>, MemberId),
}

View file

@ -37,7 +37,7 @@ ace.define("ace/mode/zokrates_highlight_rules",["require","exports","module","ac
var ZoKratesHighlightRules = function () {
var keywords = (
"assert|as|bool|byte|const|def|do|else|endfor|export|false|field|for|if|then|fi|import|from|in|private|public|return|struct|true|u8|u16|u32|u64"
"assert|as|bool|byte|const|def|do|else|endfor|export|false|field|for|if|then|fi|import|from|in|private|public|return|struct|true|type|u8|u16|u32|u64"
);
var keywordMapper = this.createKeywordMapper({

View file

@ -202,19 +202,23 @@ repository:
-
comment: 'control flow keywords'
name: keyword.control.zokrates
match: \b(do|else|for|do|endfor|if|then|fi|return|assert)\b
match: \b(for|in|do|endfor|if|then|else|fi|return|assert)\b
-
comment: 'storage keywords'
name: storage.type.zokrates
match: \b(struct)\b
-
comment: const
comment: 'const keyword'
name: keyword.other.const.zokrates
match: \bconst\b
match: \b(const)\b
-
comment: def
comment: 'type keyword'
name: keyword.other.type.zokrates
match: \b(type)\b
-
comment: 'def keyword'
name: keyword.other.def.zokrates
match: \bdef\b
match: \b(def)\b
-
comment: 'import keywords'
name: keyword.other.import.zokrates