feat(bls): aiken level g1 and g2 literals
This commit is contained in:
parent
90aea6476a
commit
3675762c3e
|
@ -82,6 +82,7 @@ dependencies = [
|
|||
name = "aiken-lang"
|
||||
version = "1.0.20-alpha"
|
||||
dependencies = [
|
||||
"blst",
|
||||
"chumsky",
|
||||
"hex",
|
||||
"indexmap",
|
||||
|
|
|
@ -27,6 +27,7 @@ vec1 = "1.10.1"
|
|||
uplc = { path = '../uplc', version = "1.0.20-alpha" }
|
||||
num-bigint = "0.4.3"
|
||||
petgraph = "0.6.3"
|
||||
blst = "0.3.11"
|
||||
|
||||
[target.'cfg(not(target_family="wasm"))'.dependencies]
|
||||
chumsky = "0.9.2"
|
||||
|
|
|
@ -11,6 +11,7 @@ use std::{
|
|||
ops::Range,
|
||||
rc::Rc,
|
||||
};
|
||||
use uplc::machine::runtime::Compressable;
|
||||
use vec1::Vec1;
|
||||
|
||||
pub const CAPTURE_VARIABLE: &str = "_capture";
|
||||
|
@ -492,6 +493,12 @@ pub enum Constant {
|
|||
bytes: Vec<u8>,
|
||||
preferred_format: ByteArrayFormatPreference,
|
||||
},
|
||||
|
||||
CurvePoint {
|
||||
location: Span,
|
||||
point: Curve,
|
||||
preferred_format: ByteArrayFormatPreference,
|
||||
},
|
||||
}
|
||||
|
||||
impl Constant {
|
||||
|
@ -500,6 +507,10 @@ impl Constant {
|
|||
Constant::Int { .. } => builtins::int(),
|
||||
Constant::String { .. } => builtins::string(),
|
||||
Constant::ByteArray { .. } => builtins::byte_array(),
|
||||
Constant::CurvePoint { point, .. } => match point {
|
||||
Curve::Bls12_381(Bls12_381Point::G1(_)) => builtins::g1_element(),
|
||||
Curve::Bls12_381(Bls12_381Point::G2(_)) => builtins::g2_element(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -507,7 +518,8 @@ impl Constant {
|
|||
match self {
|
||||
Constant::Int { location, .. }
|
||||
| Constant::String { location, .. }
|
||||
| Constant::ByteArray { location, .. } => *location,
|
||||
| Constant::ByteArray { location, .. }
|
||||
| Constant::CurvePoint { location, .. } => *location,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -997,6 +1009,78 @@ pub enum ByteArrayFormatPreference {
|
|||
Utf8String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
|
||||
pub enum CurveType {
|
||||
Bls12_381(Bls12_381PointType),
|
||||
}
|
||||
|
||||
impl Display for CurveType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
CurveType::Bls12_381(point) => write!(f, "<Bls12_381, {point}>"),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl From<&Curve> for CurveType {
|
||||
fn from(value: &Curve) -> Self {
|
||||
match value {
|
||||
Curve::Bls12_381(point) => CurveType::Bls12_381(point.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
|
||||
pub enum Bls12_381PointType {
|
||||
G1,
|
||||
G2,
|
||||
}
|
||||
|
||||
impl From<&Bls12_381Point> for Bls12_381PointType {
|
||||
fn from(value: &Bls12_381Point) -> Self {
|
||||
match value {
|
||||
Bls12_381Point::G1(_) => Bls12_381PointType::G1,
|
||||
Bls12_381Point::G2(_) => Bls12_381PointType::G2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Bls12_381PointType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Bls12_381PointType::G1 => write!(f, "G1"),
|
||||
Bls12_381PointType::G2 => write!(f, "G2"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
|
||||
pub enum Curve {
|
||||
Bls12_381(Bls12_381Point),
|
||||
}
|
||||
|
||||
impl Curve {
|
||||
pub fn compress(&self) -> Vec<u8> {
|
||||
match self {
|
||||
Curve::Bls12_381(point) => match point {
|
||||
Bls12_381Point::G1(g1) => g1.compress(),
|
||||
Bls12_381Point::G2(g2) => g2.compress(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
|
||||
pub enum Bls12_381Point {
|
||||
G1(blst::blst_p1),
|
||||
G2(blst::blst_p2),
|
||||
}
|
||||
|
||||
impl Default for Bls12_381Point {
|
||||
fn default() -> Self {
|
||||
Bls12_381Point::G1(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
|
||||
pub enum AssignmentKind {
|
||||
Let,
|
||||
|
|
|
@ -4,7 +4,7 @@ use vec1::Vec1;
|
|||
|
||||
use crate::{
|
||||
ast::{
|
||||
self, Annotation, Arg, AssignmentKind, BinOp, ByteArrayFormatPreference, CallArg,
|
||||
self, Annotation, Arg, AssignmentKind, BinOp, ByteArrayFormatPreference, CallArg, Curve,
|
||||
DefinitionLocation, IfBranch, Located, LogicalOpChainKind, ParsedCallArg, Pattern,
|
||||
RecordUpdateSpread, Span, TraceKind, TypedClause, TypedRecordUpdateArg, UnOp,
|
||||
UntypedClause, UntypedRecordUpdateArg,
|
||||
|
@ -34,6 +34,12 @@ pub enum TypedExpr {
|
|||
bytes: Vec<u8>,
|
||||
},
|
||||
|
||||
CurvePoint {
|
||||
location: Span,
|
||||
tipo: Rc<Type>,
|
||||
point: Curve,
|
||||
},
|
||||
|
||||
Sequence {
|
||||
location: Span,
|
||||
expressions: Vec<Self>,
|
||||
|
@ -186,7 +192,8 @@ impl TypedExpr {
|
|||
| Self::Assignment { tipo, .. }
|
||||
| Self::ModuleSelect { tipo, .. }
|
||||
| Self::RecordAccess { tipo, .. }
|
||||
| Self::RecordUpdate { tipo, .. } => tipo.clone(),
|
||||
| Self::RecordUpdate { tipo, .. }
|
||||
| Self::CurvePoint { tipo, .. } => tipo.clone(),
|
||||
Self::Pipeline { expressions, .. } | Self::Sequence { expressions, .. } => {
|
||||
expressions.last().map(TypedExpr::tipo).unwrap_or_else(void)
|
||||
}
|
||||
|
@ -227,7 +234,8 @@ impl TypedExpr {
|
|||
| TypedExpr::ByteArray { .. }
|
||||
| TypedExpr::Assignment { .. }
|
||||
| TypedExpr::TupleIndex { .. }
|
||||
| TypedExpr::RecordAccess { .. } => None,
|
||||
| TypedExpr::RecordAccess { .. }
|
||||
| TypedExpr::CurvePoint { .. } => None,
|
||||
TypedExpr::If { .. } => None,
|
||||
|
||||
// TODO: test
|
||||
|
@ -269,7 +277,8 @@ impl TypedExpr {
|
|||
| Self::TupleIndex { location, .. }
|
||||
| Self::ModuleSelect { location, .. }
|
||||
| Self::RecordAccess { location, .. }
|
||||
| Self::RecordUpdate { location, .. } => *location,
|
||||
| Self::RecordUpdate { location, .. }
|
||||
| Self::CurvePoint { location, .. } => *location,
|
||||
|
||||
Self::If { branches, .. } => branches.first().body.type_defining_location(),
|
||||
|
||||
|
@ -306,7 +315,8 @@ impl TypedExpr {
|
|||
| Self::TupleIndex { location, .. }
|
||||
| Self::ModuleSelect { location, .. }
|
||||
| Self::RecordAccess { location, .. }
|
||||
| Self::RecordUpdate { location, .. } => *location,
|
||||
| Self::RecordUpdate { location, .. }
|
||||
| Self::CurvePoint { location, .. } => *location,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -323,7 +333,8 @@ impl TypedExpr {
|
|||
| TypedExpr::UInt { .. }
|
||||
| TypedExpr::String { .. }
|
||||
| TypedExpr::ByteArray { .. }
|
||||
| TypedExpr::ModuleSelect { .. } => Some(Located::Expression(self)),
|
||||
| TypedExpr::ModuleSelect { .. }
|
||||
| TypedExpr::CurvePoint { .. } => Some(Located::Expression(self)),
|
||||
|
||||
TypedExpr::Trace { text, then, .. } => text
|
||||
.find_node(byte_index)
|
||||
|
@ -472,6 +483,12 @@ pub enum UntypedExpr {
|
|||
preferred_format: ByteArrayFormatPreference,
|
||||
},
|
||||
|
||||
CurvePoint {
|
||||
location: Span,
|
||||
point: Curve,
|
||||
preferred_format: ByteArrayFormatPreference,
|
||||
},
|
||||
|
||||
PipeLine {
|
||||
expressions: Vec1<Self>,
|
||||
one_liner: bool,
|
||||
|
@ -733,7 +750,8 @@ impl UntypedExpr {
|
|||
| Self::RecordUpdate { location, .. }
|
||||
| Self::UnOp { location, .. }
|
||||
| Self::LogicalOpChain { location, .. }
|
||||
| Self::If { location, .. } => *location,
|
||||
| Self::If { location, .. }
|
||||
| Self::CurvePoint { location, .. } => *location,
|
||||
Self::Sequence {
|
||||
location,
|
||||
expressions,
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use crate::{
|
||||
ast::{
|
||||
Annotation, Arg, ArgName, AssignmentKind, BinOp, ByteArrayFormatPreference, CallArg,
|
||||
ClauseGuard, Constant, DataType, Definition, Function, IfBranch, LogicalOpChainKind,
|
||||
ModuleConstant, Pattern, RecordConstructor, RecordConstructorArg, RecordUpdateSpread, Span,
|
||||
TraceKind, TypeAlias, TypedArg, UnOp, UnqualifiedImport, UntypedArg, UntypedClause,
|
||||
UntypedClauseGuard, UntypedDefinition, UntypedFunction, UntypedModule, UntypedPattern,
|
||||
UntypedRecordUpdateArg, Use, Validator, CAPTURE_VARIABLE,
|
||||
ClauseGuard, Constant, CurveType, DataType, Definition, Function, IfBranch,
|
||||
LogicalOpChainKind, ModuleConstant, Pattern, RecordConstructor, RecordConstructorArg,
|
||||
RecordUpdateSpread, Span, TraceKind, TypeAlias, TypedArg, UnOp, UnqualifiedImport,
|
||||
UntypedArg, UntypedClause, UntypedClauseGuard, UntypedDefinition, UntypedFunction,
|
||||
UntypedModule, UntypedPattern, UntypedRecordUpdateArg, Use, Validator, CAPTURE_VARIABLE,
|
||||
},
|
||||
docvec,
|
||||
expr::{FnStyle, UntypedExpr, DEFAULT_ERROR_STR, DEFAULT_TODO_STR},
|
||||
|
@ -352,7 +352,12 @@ impl<'comments> Formatter<'comments> {
|
|||
bytes,
|
||||
preferred_format,
|
||||
..
|
||||
} => self.bytearray(bytes, preferred_format),
|
||||
} => self.bytearray(bytes, None, preferred_format),
|
||||
Constant::CurvePoint {
|
||||
point,
|
||||
preferred_format,
|
||||
..
|
||||
} => self.bytearray(&point.compress(), Some(point.into()), preferred_format),
|
||||
Constant::Int { value, base, .. } => self.int(value, base),
|
||||
Constant::String { value, .. } => self.string(value),
|
||||
}
|
||||
|
@ -676,17 +681,24 @@ impl<'comments> Formatter<'comments> {
|
|||
|
||||
pub fn bytearray<'a>(
|
||||
&mut self,
|
||||
bytes: &'a [u8],
|
||||
bytes: &[u8],
|
||||
curve: Option<CurveType>,
|
||||
preferred_format: &ByteArrayFormatPreference,
|
||||
) -> Document<'a> {
|
||||
match preferred_format {
|
||||
ByteArrayFormatPreference::HexadecimalString => "#"
|
||||
.to_doc()
|
||||
.append(Document::String(
|
||||
curve.map(|c| c.to_string()).unwrap_or_default(),
|
||||
))
|
||||
.append("\"")
|
||||
.append(Document::String(hex::encode(bytes)))
|
||||
.append("\""),
|
||||
ByteArrayFormatPreference::ArrayOfBytes(Base::Decimal { .. }) => "#"
|
||||
.to_doc()
|
||||
.append(Document::String(
|
||||
curve.map(|c| c.to_string()).unwrap_or_default(),
|
||||
))
|
||||
.append(
|
||||
flex_break("[", "[")
|
||||
.append(join(bytes.iter().map(|b| b.to_doc()), break_(",", ", ")))
|
||||
|
@ -697,6 +709,9 @@ impl<'comments> Formatter<'comments> {
|
|||
.group(),
|
||||
ByteArrayFormatPreference::ArrayOfBytes(Base::Hexadecimal) => "#"
|
||||
.to_doc()
|
||||
.append(Document::String(
|
||||
curve.map(|c| c.to_string()).unwrap_or_default(),
|
||||
))
|
||||
.append(
|
||||
flex_break("[", "[")
|
||||
.append(join(
|
||||
|
@ -771,7 +786,13 @@ impl<'comments> Formatter<'comments> {
|
|||
bytes,
|
||||
preferred_format,
|
||||
..
|
||||
} => self.bytearray(bytes, preferred_format),
|
||||
} => self.bytearray(bytes, None, preferred_format),
|
||||
|
||||
UntypedExpr::CurvePoint {
|
||||
point,
|
||||
preferred_format,
|
||||
..
|
||||
} => self.bytearray(&point.compress(), Some(point.into()), preferred_format),
|
||||
|
||||
UntypedExpr::If {
|
||||
branches,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use chumsky::prelude::*;
|
||||
use uplc::machine::runtime::Compressable;
|
||||
|
||||
use crate::{
|
||||
ast,
|
||||
|
@ -45,13 +46,36 @@ pub fn value() -> impl Parser<Token, ast::Constant, Error = ParseError> {
|
|||
base,
|
||||
});
|
||||
|
||||
let constant_bytearray_parser =
|
||||
literal::bytearray(
|
||||
|bytes, preferred_format, location| ast::Constant::ByteArray {
|
||||
let constant_bytearray_parser = literal::bytearray(
|
||||
|bytes, preferred_format, curve, location, emit| match curve {
|
||||
Some(curve @ ast::CurveType::Bls12_381(point)) => {
|
||||
let point = match point {
|
||||
ast::Bls12_381PointType::G1 => {
|
||||
blst::blst_p1::uncompress(&bytes).map(ast::Bls12_381Point::G1)
|
||||
}
|
||||
ast::Bls12_381PointType::G2 => {
|
||||
blst::blst_p2::uncompress(&bytes).map(ast::Bls12_381Point::G2)
|
||||
}
|
||||
};
|
||||
|
||||
let point = point.unwrap_or_else(|_err| {
|
||||
emit(ParseError::point_not_on_curve(curve, location));
|
||||
|
||||
ast::Bls12_381Point::default()
|
||||
});
|
||||
|
||||
ast::Constant::CurvePoint {
|
||||
location,
|
||||
point: ast::Curve::Bls12_381(point),
|
||||
preferred_format,
|
||||
}
|
||||
}
|
||||
None => ast::Constant::ByteArray {
|
||||
location,
|
||||
bytes,
|
||||
preferred_format,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
choice((
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
use crate::{ast::Span, parser::token::Token};
|
||||
use crate::{
|
||||
ast::{CurveType, Span},
|
||||
parser::token::Token,
|
||||
};
|
||||
use indoc::formatdoc;
|
||||
use miette::Diagnostic;
|
||||
use owo_colors::{OwoColorize, Stream::Stdout};
|
||||
|
@ -46,6 +49,32 @@ impl ParseError {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn point_not_on_curve(curve: CurveType, span: Span) -> Self {
|
||||
Self {
|
||||
kind: ErrorKind::PointNotOnCurve { curve },
|
||||
span,
|
||||
while_parsing: None,
|
||||
expected: HashSet::new(),
|
||||
label: Some("out off curve"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unknown_point_curve(curve: String, point: Option<String>, span: Span) -> Self {
|
||||
let label = if point.is_some() {
|
||||
Some("unknown curve")
|
||||
} else {
|
||||
Some("unknown point")
|
||||
};
|
||||
|
||||
Self {
|
||||
kind: ErrorKind::UnknownCurvePoint { curve, point },
|
||||
span,
|
||||
while_parsing: None,
|
||||
expected: HashSet::new(),
|
||||
label,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn malformed_base16_string_literal(span: Span) -> Self {
|
||||
Self {
|
||||
kind: ErrorKind::MalformedBase16StringLiteral,
|
||||
|
@ -134,6 +163,15 @@ pub enum ErrorKind {
|
|||
hint: Option<String>,
|
||||
},
|
||||
|
||||
#[error("I tripped over a {}", fmt_curve_type(.curve))]
|
||||
PointNotOnCurve { curve: CurveType },
|
||||
|
||||
#[error("I tripped over a {}", fmt_unknown_curve(.curve, .point))]
|
||||
UnknownCurvePoint {
|
||||
curve: String,
|
||||
point: Option<String>,
|
||||
},
|
||||
|
||||
#[error("I tripped over a malformed hexadecimal digits.")]
|
||||
#[diagnostic(help("{}", formatdoc! {
|
||||
r#"When numbers starts with '0x', they are treated as hexadecimal numbers. Thus, only digits from 0-9 or letter from a-f (or A-F) can be used following a '0x' number declaration. Plus, hexadecimal digits always go by pairs, so the total number of digits must be even (not counting leading zeros)."#
|
||||
|
@ -186,6 +224,32 @@ pub enum ErrorKind {
|
|||
InvalidWhenClause,
|
||||
}
|
||||
|
||||
fn fmt_curve_type(curve: &CurveType) -> String {
|
||||
match curve {
|
||||
CurveType::Bls12_381(point) => {
|
||||
format!("{point} point that is not in the bls12_381 curve")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fmt_unknown_curve(curve: &String, point: &Option<String>) -> String {
|
||||
match point {
|
||||
Some(point) => {
|
||||
format!(
|
||||
"{} which is an unknown point for curve {}",
|
||||
point.if_supports_color(Stdout, |s| s.purple()),
|
||||
curve.if_supports_color(Stdout, |s| s.purple()),
|
||||
)
|
||||
}
|
||||
None => {
|
||||
format!(
|
||||
"{} which is an unknown curve",
|
||||
curve.if_supports_color(Stdout, |s| s.purple())
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Diagnostic, thiserror::Error)]
|
||||
pub enum Pattern {
|
||||
#[error("I found an unexpected char '{0:?}'.")]
|
||||
|
|
|
@ -1,13 +1,43 @@
|
|||
use chumsky::prelude::*;
|
||||
use uplc::machine::runtime::Compressable;
|
||||
|
||||
use crate::parser::{error::ParseError, expr::UntypedExpr, literal::bytearray, token::Token};
|
||||
use crate::{
|
||||
ast,
|
||||
parser::{error::ParseError, expr::UntypedExpr, literal::bytearray, token::Token},
|
||||
};
|
||||
|
||||
pub fn parser() -> impl Parser<Token, UntypedExpr, Error = ParseError> {
|
||||
bytearray(|bytes, preferred_format, location| UntypedExpr::ByteArray {
|
||||
bytearray(
|
||||
|bytes, preferred_format, curve, location, emit| match curve {
|
||||
Some(curve @ ast::CurveType::Bls12_381(point)) => {
|
||||
let point = match point {
|
||||
ast::Bls12_381PointType::G1 => {
|
||||
blst::blst_p1::uncompress(&bytes).map(ast::Bls12_381Point::G1)
|
||||
}
|
||||
ast::Bls12_381PointType::G2 => {
|
||||
blst::blst_p2::uncompress(&bytes).map(ast::Bls12_381Point::G2)
|
||||
}
|
||||
};
|
||||
|
||||
let point = point.unwrap_or_else(|_err| {
|
||||
emit(ParseError::point_not_on_curve(curve, location));
|
||||
|
||||
ast::Bls12_381Point::default()
|
||||
});
|
||||
|
||||
UntypedExpr::CurvePoint {
|
||||
location,
|
||||
point: ast::Curve::Bls12_381(point),
|
||||
preferred_format,
|
||||
}
|
||||
}
|
||||
None => UntypedExpr::ByteArray {
|
||||
location,
|
||||
bytes,
|
||||
preferred_format,
|
||||
})
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -9,16 +9,70 @@ use crate::{
|
|||
};
|
||||
|
||||
pub fn parser<A>(
|
||||
into: impl Fn(Vec<u8>, ast::ByteArrayFormatPreference, ast::Span) -> A,
|
||||
into: impl Fn(
|
||||
Vec<u8>,
|
||||
ast::ByteArrayFormatPreference,
|
||||
Option<ast::CurveType>,
|
||||
ast::Span,
|
||||
&mut dyn FnMut(ParseError),
|
||||
) -> A,
|
||||
) -> impl Parser<Token, A, Error = ParseError> {
|
||||
choice((array_of_bytes(), hex_string(), utf8_string()))
|
||||
.map_with_span(move |(preferred_format, bytes), span| into(bytes, preferred_format, span))
|
||||
choice((
|
||||
array_of_bytes(),
|
||||
hex_string(),
|
||||
utf8_string().map(|(p, b)| (None, p, b)),
|
||||
))
|
||||
.validate(move |(curve, preferred_format, bytes), span, emit| {
|
||||
into(bytes, preferred_format, curve, span, emit)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn array_of_bytes(
|
||||
) -> impl Parser<Token, (ast::ByteArrayFormatPreference, Vec<u8>), Error = ParseError> {
|
||||
fn curve_point() -> impl Parser<Token, ast::CurveType, Error = ParseError> {
|
||||
just(Token::Less)
|
||||
.ignore_then(select! {Token::UpName {name} => name})
|
||||
.then_ignore(just(Token::Comma))
|
||||
.then(select! {Token::UpName {name} => name})
|
||||
.then_ignore(just(Token::Greater))
|
||||
.validate(
|
||||
|(curve_type, point_type), span, emit| match curve_type.as_str() {
|
||||
"Bls12_381" => {
|
||||
let point = match point_type.as_str() {
|
||||
"G1" => ast::Bls12_381PointType::G1,
|
||||
"G2" => ast::Bls12_381PointType::G2,
|
||||
_ => {
|
||||
emit(ParseError::unknown_point_curve(
|
||||
curve_type,
|
||||
Some(point_type),
|
||||
span,
|
||||
));
|
||||
|
||||
ast::Bls12_381PointType::G1
|
||||
}
|
||||
};
|
||||
|
||||
ast::CurveType::Bls12_381(point)
|
||||
}
|
||||
_ => {
|
||||
emit(ParseError::unknown_point_curve(curve_type, None, span));
|
||||
|
||||
ast::CurveType::Bls12_381(ast::Bls12_381PointType::G1)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn array_of_bytes() -> impl Parser<
|
||||
Token,
|
||||
(
|
||||
Option<ast::CurveType>,
|
||||
ast::ByteArrayFormatPreference,
|
||||
Vec<u8>,
|
||||
),
|
||||
Error = ParseError,
|
||||
> {
|
||||
just(Token::Hash)
|
||||
.ignore_then(
|
||||
.ignore_then(curve_point().or_not())
|
||||
.then(
|
||||
select! {Token::Int {value, base, ..} => (value, base)}
|
||||
.validate(|(value, base), span, emit| {
|
||||
let byte: u8 = match value.parse() {
|
||||
|
@ -38,7 +92,7 @@ pub fn array_of_bytes(
|
|||
.allow_trailing()
|
||||
.delimited_by(just(Token::LeftSquare), just(Token::RightSquare)),
|
||||
)
|
||||
.validate(|bytes, span, emit| {
|
||||
.validate(|(curve, bytes), span, emit| {
|
||||
let base = bytes.iter().try_fold(None, |acc, (_, base)| match acc {
|
||||
None => Ok(Some(base)),
|
||||
Some(previous_base) if previous_base == base => Ok(Some(base)),
|
||||
|
@ -58,15 +112,33 @@ pub fn array_of_bytes(
|
|||
Ok(Some(base)) => *base,
|
||||
};
|
||||
|
||||
(bytes.into_iter().map(|(b, _)| b).collect::<Vec<u8>>(), base)
|
||||
(
|
||||
curve,
|
||||
bytes.into_iter().map(|(b, _)| b).collect::<Vec<u8>>(),
|
||||
base,
|
||||
)
|
||||
})
|
||||
.map(|(curve, bytes, base)| {
|
||||
(
|
||||
curve,
|
||||
ast::ByteArrayFormatPreference::ArrayOfBytes(base),
|
||||
bytes,
|
||||
)
|
||||
})
|
||||
.map(|(bytes, base)| (ast::ByteArrayFormatPreference::ArrayOfBytes(base), bytes))
|
||||
}
|
||||
|
||||
pub fn hex_string(
|
||||
) -> impl Parser<Token, (ast::ByteArrayFormatPreference, Vec<u8>), Error = ParseError> {
|
||||
pub fn hex_string() -> impl Parser<
|
||||
Token,
|
||||
(
|
||||
Option<ast::CurveType>,
|
||||
ast::ByteArrayFormatPreference,
|
||||
Vec<u8>,
|
||||
),
|
||||
Error = ParseError,
|
||||
> {
|
||||
just(Token::Hash)
|
||||
.ignore_then(
|
||||
.ignore_then(curve_point().or_not())
|
||||
.then(
|
||||
select! {Token::ByteString {value} => value}.validate(|value, span, emit| {
|
||||
match hex::decode(value) {
|
||||
Ok(bytes) => bytes,
|
||||
|
@ -77,7 +149,13 @@ pub fn hex_string(
|
|||
}
|
||||
}),
|
||||
)
|
||||
.map(|token| (ast::ByteArrayFormatPreference::HexadecimalString, token))
|
||||
.map(|(curve, token)| {
|
||||
(
|
||||
curve,
|
||||
ast::ByteArrayFormatPreference::HexadecimalString,
|
||||
token,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn utf8_string(
|
||||
|
|
|
@ -3,13 +3,13 @@ use vec1::Vec1;
|
|||
|
||||
use crate::{
|
||||
ast::{
|
||||
Annotation, Arg, ArgName, AssignmentKind, BinOp, ByteArrayFormatPreference, CallArg,
|
||||
ClauseGuard, Constant, IfBranch, LogicalOpChainKind, RecordUpdateSpread, Span, TraceKind,
|
||||
Tracing, TypedArg, TypedCallArg, TypedClause, TypedClauseGuard, TypedIfBranch,
|
||||
TypedPattern, TypedRecordUpdateArg, UnOp, UntypedArg, UntypedClause, UntypedClauseGuard,
|
||||
UntypedIfBranch, UntypedPattern, UntypedRecordUpdateArg,
|
||||
Annotation, Arg, ArgName, AssignmentKind, BinOp, Bls12_381Point, ByteArrayFormatPreference,
|
||||
CallArg, ClauseGuard, Constant, Curve, IfBranch, LogicalOpChainKind, RecordUpdateSpread,
|
||||
Span, TraceKind, Tracing, TypedArg, TypedCallArg, TypedClause, TypedClauseGuard,
|
||||
TypedIfBranch, TypedPattern, TypedRecordUpdateArg, UnOp, UntypedArg, UntypedClause,
|
||||
UntypedClauseGuard, UntypedIfBranch, UntypedPattern, UntypedRecordUpdateArg,
|
||||
},
|
||||
builtins::{bool, byte_array, function, int, list, string, tuple},
|
||||
builtins::{bool, byte_array, function, g1_element, g2_element, int, list, string, tuple},
|
||||
expr::{FnStyle, TypedExpr, UntypedExpr},
|
||||
format,
|
||||
tipo::fields::FieldMap,
|
||||
|
@ -321,6 +321,10 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
location,
|
||||
} => self.infer_bytearray(bytes, preferred_format, location),
|
||||
|
||||
UntypedExpr::CurvePoint {
|
||||
location, point, ..
|
||||
} => self.infer_curve_point(point, location),
|
||||
|
||||
UntypedExpr::RecordUpdate {
|
||||
location,
|
||||
constructor,
|
||||
|
@ -363,6 +367,21 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
})
|
||||
}
|
||||
|
||||
fn infer_curve_point(&mut self, curve: Curve, location: Span) -> Result<TypedExpr, Error> {
|
||||
let tipo = match curve {
|
||||
Curve::Bls12_381(point) => match point {
|
||||
Bls12_381Point::G1(_) => g1_element(),
|
||||
Bls12_381Point::G2(_) => g2_element(),
|
||||
},
|
||||
};
|
||||
|
||||
Ok(TypedExpr::CurvePoint {
|
||||
location,
|
||||
point: curve,
|
||||
tipo,
|
||||
})
|
||||
}
|
||||
|
||||
fn infer_trace_if_false(
|
||||
&mut self,
|
||||
value: UntypedExpr,
|
||||
|
@ -1345,6 +1364,15 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
preferred_format,
|
||||
})
|
||||
}
|
||||
Constant::CurvePoint {
|
||||
location,
|
||||
point,
|
||||
preferred_format,
|
||||
} => Ok(Constant::CurvePoint {
|
||||
location,
|
||||
point,
|
||||
preferred_format,
|
||||
}),
|
||||
}?;
|
||||
|
||||
// Check type annotation is accurate.
|
||||
|
@ -2000,7 +2028,8 @@ fn assert_no_assignment(expr: &UntypedExpr) -> Result<(), Error> {
|
|||
| UntypedExpr::Var { .. }
|
||||
| UntypedExpr::LogicalOpChain { .. }
|
||||
| UntypedExpr::TraceIfFalse { .. }
|
||||
| UntypedExpr::When { .. } => Ok(()),
|
||||
| UntypedExpr::When { .. }
|
||||
| UntypedExpr::CurvePoint { .. } => Ok(()),
|
||||
}
|
||||
}
|
||||
fn assert_assignment(expr: &UntypedExpr) -> Result<(), Error> {
|
||||
|
|
Loading…
Reference in New Issue