mirror of
https://github.com/AleoHQ/leo.git
synced 2024-12-28 20:14:11 +03:00
commit
f6e602347a
Cargo.lock
asg
Cargo.toml
src
ast
compiler
src
compiler.rs
constraints
errors
expression
function
prelude
value/integer
tests/canonicalization
imports/src/errors
parser
state/src/utilities
42
Cargo.lock
generated
42
Cargo.lock
generated
@ -787,6 +787,16 @@ version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
|
||||
[[package]]
|
||||
name = "futf"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b"
|
||||
dependencies = [
|
||||
"mac",
|
||||
"new_debug_unreachable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.13"
|
||||
@ -1203,6 +1213,7 @@ dependencies = [
|
||||
"num-bigint",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tendril",
|
||||
"thiserror",
|
||||
"typed-arena",
|
||||
]
|
||||
@ -1225,6 +1236,7 @@ dependencies = [
|
||||
"pest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tendril",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
@ -1351,6 +1363,7 @@ dependencies = [
|
||||
"leo-ast",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tendril",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
]
|
||||
@ -1444,6 +1457,12 @@ dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mac"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
|
||||
|
||||
[[package]]
|
||||
name = "maplit"
|
||||
version = "1.0.2"
|
||||
@ -1610,6 +1629,12 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "new_debug_unreachable"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
||||
|
||||
[[package]]
|
||||
name = "nias"
|
||||
version = "0.5.0"
|
||||
@ -2759,6 +2784,17 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tendril"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9ef557cb397a4f0a5a3a628f06515f78563f2209e64d47055d9dc6052bf5e33"
|
||||
dependencies = [
|
||||
"futf",
|
||||
"mac",
|
||||
"utf-8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.2"
|
||||
@ -3077,6 +3113,12 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf-8"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.11"
|
||||
|
@ -43,5 +43,8 @@ version = "0.4"
|
||||
[dependencies.typed-arena]
|
||||
version = "2.0"
|
||||
|
||||
[dependencies.tendril]
|
||||
version = "0.4"
|
||||
|
||||
[dev-dependencies.criterion]
|
||||
version = "0.3"
|
||||
|
@ -18,6 +18,7 @@ use crate::{AsgConvertError, IntegerType, Span, Type};
|
||||
|
||||
use num_bigint::BigInt;
|
||||
use std::{convert::TryInto, fmt};
|
||||
use tendril::StrTendril;
|
||||
|
||||
/// Constant integer values in a program.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
@ -38,7 +39,7 @@ pub enum ConstInt {
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum GroupCoordinate {
|
||||
/// Explicit field element number string.
|
||||
Number(String),
|
||||
Number(StrTendril),
|
||||
|
||||
/// Attempt to recover with a sign high bit.
|
||||
SignHigh,
|
||||
@ -87,7 +88,7 @@ impl Into<leo_ast::GroupCoordinate> for &GroupCoordinate {
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum GroupValue {
|
||||
Single(String),
|
||||
Single(StrTendril),
|
||||
Tuple(GroupCoordinate, GroupCoordinate),
|
||||
}
|
||||
|
||||
@ -106,7 +107,7 @@ pub enum ConstValue {
|
||||
Int(ConstInt),
|
||||
Group(GroupValue),
|
||||
Field(BigInt),
|
||||
Address(String),
|
||||
Address(StrTendril),
|
||||
Boolean(bool),
|
||||
|
||||
// compounds
|
||||
|
@ -35,25 +35,7 @@ pub enum AsgConvertError {
|
||||
SyntaxError(#[from] SyntaxError),
|
||||
}
|
||||
|
||||
impl LeoError for AsgConvertError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
AsgConvertError::Error(error) => error.get_path(),
|
||||
AsgConvertError::SyntaxError(error) => error.get_path(),
|
||||
AsgConvertError::ImportError(error) => error.get_path(),
|
||||
AsgConvertError::InternalError(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
AsgConvertError::Error(error) => error.set_path(path, contents),
|
||||
AsgConvertError::SyntaxError(error) => error.set_path(path, contents),
|
||||
AsgConvertError::ImportError(error) => error.set_path(path, contents),
|
||||
AsgConvertError::InternalError(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for AsgConvertError {}
|
||||
|
||||
impl AsgConvertError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -152,7 +152,7 @@ impl<'a> Into<leo_ast::ArrayInitExpression> for &ArrayInitExpression<'a> {
|
||||
leo_ast::ArrayInitExpression {
|
||||
element: Box::new(self.element.get().into()),
|
||||
dimensions: leo_ast::ArrayDimensions(vec![leo_ast::PositiveNumber {
|
||||
value: self.len.to_string(),
|
||||
value: self.len.to_string().into(),
|
||||
}]),
|
||||
span: self.span.clone().unwrap_or_default(),
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> {
|
||||
let circuit_name = circuit.name.borrow().name.clone();
|
||||
let member = circuit.members.borrow();
|
||||
let member = member
|
||||
.get(&name.name)
|
||||
.get(name.name.as_ref())
|
||||
.ok_or_else(|| AsgConvertError::unresolved_circuit_member(&circuit_name, &name.name, span))?;
|
||||
match member {
|
||||
CircuitMember::Function(body) => {
|
||||
@ -156,7 +156,7 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> {
|
||||
|
||||
let member = circuit.members.borrow();
|
||||
let member = member
|
||||
.get(&name.name)
|
||||
.get(name.name.as_ref())
|
||||
.ok_or_else(|| AsgConvertError::unresolved_circuit_member(&circuit_name, &name.name, span))?;
|
||||
match member {
|
||||
CircuitMember::Function(body) => {
|
||||
|
@ -67,7 +67,7 @@ impl<'a> ExpressionNode<'a> for CircuitAccessExpression<'a> {
|
||||
None // function target only for static
|
||||
} else {
|
||||
let members = self.circuit.get().members.borrow();
|
||||
let member = members.get(&self.member.name)?;
|
||||
let member = members.get(self.member.name.as_ref())?;
|
||||
match member {
|
||||
CircuitMember::Variable(type_) => Some(type_.clone()),
|
||||
CircuitMember::Function(_) => None,
|
||||
@ -112,7 +112,7 @@ impl<'a> FromAst<'a, leo_ast::CircuitMemberAccessExpression> for CircuitAccessEx
|
||||
|
||||
// scoping refcell reference
|
||||
let found_member = {
|
||||
if let Some(member) = circuit.members.borrow().get(&value.name.name) {
|
||||
if let Some(member) = circuit.members.borrow().get(value.name.name.as_ref()) {
|
||||
if let Some(expected_type) = &expected_type {
|
||||
if let CircuitMember::Variable(type_) = &member {
|
||||
let type_: Type = type_.clone();
|
||||
@ -136,10 +136,10 @@ impl<'a> FromAst<'a, leo_ast::CircuitMemberAccessExpression> for CircuitAccessEx
|
||||
} else if circuit.is_input_pseudo_circuit() {
|
||||
// add new member to implicit input
|
||||
if let Some(expected_type) = expected_type.map(PartialType::full).flatten() {
|
||||
circuit
|
||||
.members
|
||||
.borrow_mut()
|
||||
.insert(value.name.name.clone(), CircuitMember::Variable(expected_type.clone()));
|
||||
circuit.members.borrow_mut().insert(
|
||||
value.name.name.to_string(),
|
||||
CircuitMember::Variable(expected_type.clone()),
|
||||
);
|
||||
} else {
|
||||
return Err(AsgConvertError::input_ref_needs_type(
|
||||
&circuit.name.borrow().name,
|
||||
@ -192,7 +192,7 @@ impl<'a> FromAst<'a, leo_ast::CircuitStaticFunctionAccessExpression> for Circuit
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(CircuitMember::Function(_)) = circuit.members.borrow().get(&value.name.name) {
|
||||
if let Some(CircuitMember::Function(_)) = circuit.members.borrow().get(value.name.name.as_ref()) {
|
||||
// okay
|
||||
} else {
|
||||
return Err(AsgConvertError::unresolved_circuit_member(
|
||||
|
@ -99,10 +99,10 @@ impl<'a> FromAst<'a, leo_ast::CircuitInitExpression> for CircuitInitExpression<'
|
||||
));
|
||||
}
|
||||
}
|
||||
let members: IndexMap<&String, (&Identifier, Option<&leo_ast::Expression>)> = value
|
||||
let members: IndexMap<&str, (&Identifier, Option<&leo_ast::Expression>)> = value
|
||||
.members
|
||||
.iter()
|
||||
.map(|x| (&x.identifier.name, (&x.identifier, x.expression.as_ref())))
|
||||
.map(|x| (x.identifier.name.as_ref(), (&x.identifier, x.expression.as_ref())))
|
||||
.collect();
|
||||
|
||||
let mut values: Vec<(Identifier, Cell<&'a Expression<'a>>)> = vec![];
|
||||
@ -124,7 +124,7 @@ impl<'a> FromAst<'a, leo_ast::CircuitInitExpression> for CircuitInitExpression<'
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
if let Some((identifier, receiver)) = members.get(&name) {
|
||||
if let Some((identifier, receiver)) = members.get(&**name) {
|
||||
let received = if let Some(receiver) = *receiver {
|
||||
<&Expression<'a>>::from_ast(scope, receiver, Some(type_.partial()))?
|
||||
} else {
|
||||
|
@ -174,12 +174,12 @@ impl<'a> FromAst<'a, leo_ast::ValueExpression> for Constant<'a> {
|
||||
Some(PartialType::Type(Type::Group)) => Constant {
|
||||
parent: Cell::new(None),
|
||||
span: Some(span.clone()),
|
||||
value: ConstValue::Group(GroupValue::Single(value.to_string())),
|
||||
value: ConstValue::Group(GroupValue::Single(value.clone())),
|
||||
},
|
||||
Some(PartialType::Type(Type::Address)) => Constant {
|
||||
parent: Cell::new(None),
|
||||
span: Some(span.clone()),
|
||||
value: ConstValue::Address(value.to_string()),
|
||||
value: ConstValue::Address(value.clone()),
|
||||
},
|
||||
Some(x) => return Err(AsgConvertError::unexpected_type(&x.to_string(), Some("unknown"), span)),
|
||||
},
|
||||
@ -213,10 +213,10 @@ impl<'a> Into<leo_ast::ValueExpression> for &Constant<'a> {
|
||||
leo_ast::ValueExpression::Address(value.clone(), self.span.clone().unwrap_or_default())
|
||||
}
|
||||
ConstValue::Boolean(value) => {
|
||||
leo_ast::ValueExpression::Boolean(value.to_string(), self.span.clone().unwrap_or_default())
|
||||
leo_ast::ValueExpression::Boolean(value.to_string().into(), self.span.clone().unwrap_or_default())
|
||||
}
|
||||
ConstValue::Field(value) => {
|
||||
leo_ast::ValueExpression::Field(value.to_string(), self.span.clone().unwrap_or_default())
|
||||
leo_ast::ValueExpression::Field(value.to_string().into(), self.span.clone().unwrap_or_default())
|
||||
}
|
||||
ConstValue::Group(value) => leo_ast::ValueExpression::Group(Box::new(match value {
|
||||
GroupValue::Single(single) => {
|
||||
@ -230,7 +230,7 @@ impl<'a> Into<leo_ast::ValueExpression> for &Constant<'a> {
|
||||
})),
|
||||
ConstValue::Int(int) => leo_ast::ValueExpression::Integer(
|
||||
int.get_int_type(),
|
||||
int.raw_value(),
|
||||
int.raw_value().into(),
|
||||
self.span.clone().unwrap_or_default(),
|
||||
),
|
||||
ConstValue::Tuple(_) => unimplemented!(),
|
||||
|
@ -109,7 +109,7 @@ impl<'a> Into<leo_ast::TupleAccessExpression> for &TupleAccessExpression<'a> {
|
||||
leo_ast::TupleAccessExpression {
|
||||
tuple: Box::new(self.tuple_ref.get().into()),
|
||||
index: leo_ast::PositiveNumber {
|
||||
value: self.index.to_string(),
|
||||
value: self.index.to_string().into(),
|
||||
},
|
||||
span: self.span.clone().unwrap_or_default(),
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ impl<'a> FromAst<'a, leo_ast::Identifier> for &'a Expression<'a> {
|
||||
value: &leo_ast::Identifier,
|
||||
expected_type: Option<PartialType<'a>>,
|
||||
) -> Result<&'a Expression<'a>, AsgConvertError> {
|
||||
let variable = if value.name == "input" {
|
||||
let variable = if value.name.as_ref() == "input" {
|
||||
if let Some(function) = scope.resolve_current_function() {
|
||||
if !function.has_input {
|
||||
return Err(AsgConvertError::unresolved_reference(&value.name, &value.span));
|
||||
|
@ -40,7 +40,7 @@ impl<'a> Input<'a> {
|
||||
fn make_header(scope: &'a Scope<'a>, name: &str) -> &'a Circuit<'a> {
|
||||
scope.context.alloc_circuit(Circuit {
|
||||
id: scope.context.get_id(),
|
||||
name: RefCell::new(Identifier::new(name.to_string())),
|
||||
name: RefCell::new(Identifier::new(name.into())),
|
||||
members: RefCell::new(IndexMap::new()),
|
||||
core_mapping: RefCell::new(None),
|
||||
scope,
|
||||
@ -69,7 +69,7 @@ impl<'a> Input<'a> {
|
||||
|
||||
let container_circuit = input_scope.context.alloc_circuit(Circuit {
|
||||
id: scope.context.get_id(),
|
||||
name: RefCell::new(Identifier::new(CONTAINER_PSEUDO_CIRCUIT.to_string())),
|
||||
name: RefCell::new(Identifier::new(CONTAINER_PSEUDO_CIRCUIT.into())),
|
||||
members: RefCell::new(container_members),
|
||||
core_mapping: RefCell::new(None),
|
||||
scope: input_scope,
|
||||
@ -84,7 +84,7 @@ impl<'a> Input<'a> {
|
||||
container_circuit,
|
||||
container: input_scope.context.alloc_variable(RefCell::new(crate::InnerVariable {
|
||||
id: scope.context.get_id(),
|
||||
name: Identifier::new("input".to_string()),
|
||||
name: Identifier::new("input".into()),
|
||||
type_: Type::Circuit(container_circuit),
|
||||
mutable: false,
|
||||
const_: false,
|
||||
|
@ -69,7 +69,7 @@ impl<'a> Circuit<'a> {
|
||||
let mut members = circuit.members.borrow_mut();
|
||||
for member in value.members.iter() {
|
||||
if let leo_ast::CircuitMember::CircuitVariable(name, type_) = member {
|
||||
if members.contains_key(&name.name) {
|
||||
if members.contains_key(name.name.as_ref()) {
|
||||
return Err(AsgConvertError::redefined_circuit_member(
|
||||
&value.circuit_name.name,
|
||||
&name.name,
|
||||
@ -77,7 +77,7 @@ impl<'a> Circuit<'a> {
|
||||
));
|
||||
}
|
||||
members.insert(
|
||||
name.name.clone(),
|
||||
name.name.to_string(),
|
||||
CircuitMember::Variable(new_scope.resolve_ast_type(type_)?),
|
||||
);
|
||||
}
|
||||
@ -93,13 +93,13 @@ impl<'a> Circuit<'a> {
|
||||
let new_scope = scope.make_subscope();
|
||||
let circuits = scope.circuits.borrow();
|
||||
|
||||
let circuit = circuits.get(&value.circuit_name.name).unwrap();
|
||||
let circuit = circuits.get(value.circuit_name.name.as_ref()).unwrap();
|
||||
new_scope.circuit_self.replace(Some(circuit));
|
||||
|
||||
let mut members = circuit.members.borrow_mut();
|
||||
for member in value.members.iter() {
|
||||
if let leo_ast::CircuitMember::CircuitFunction(function) = member {
|
||||
if members.contains_key(&function.identifier.name) {
|
||||
if members.contains_key(function.identifier.name.as_ref()) {
|
||||
return Err(AsgConvertError::redefined_circuit_member(
|
||||
&value.circuit_name.name,
|
||||
&function.identifier.name,
|
||||
@ -111,7 +111,10 @@ impl<'a> Circuit<'a> {
|
||||
if asg_function.is_test() {
|
||||
return Err(AsgConvertError::circuit_test_function(&function.identifier.span));
|
||||
}
|
||||
members.insert(function.identifier.name.clone(), CircuitMember::Function(asg_function));
|
||||
members.insert(
|
||||
function.identifier.name.to_string(),
|
||||
CircuitMember::Function(asg_function),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,7 +129,7 @@ impl<'a> Circuit<'a> {
|
||||
let asg_function = match *self
|
||||
.members
|
||||
.borrow()
|
||||
.get(&function.identifier.name)
|
||||
.get(function.identifier.name.as_ref())
|
||||
.expect("missing header for defined circuit function")
|
||||
{
|
||||
CircuitMember::Function(f) => f,
|
||||
@ -148,7 +151,7 @@ impl<'a> Into<leo_ast::Circuit> for &Circuit<'a> {
|
||||
.iter()
|
||||
.map(|(name, member)| match &member {
|
||||
CircuitMember::Variable(type_) => {
|
||||
leo_ast::CircuitMember::CircuitVariable(Identifier::new(name.clone()), type_.into())
|
||||
leo_ast::CircuitMember::CircuitVariable(Identifier::new((&**name).into()), type_.into())
|
||||
}
|
||||
CircuitMember::Function(func) => leo_ast::CircuitMember::CircuitFunction((*func).into()),
|
||||
})
|
||||
|
@ -113,7 +113,7 @@ impl<'a> Function<'a> {
|
||||
references: vec![],
|
||||
assignments: vec![],
|
||||
}));
|
||||
arguments.insert(identifier.name.clone(), Cell::new(&*variable));
|
||||
arguments.insert(identifier.name.to_string(), Cell::new(&*variable));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -144,7 +144,7 @@ impl<'a> Function<'a> {
|
||||
let circuit = self.circuit.get();
|
||||
let self_variable = self.scope.context.alloc_variable(RefCell::new(crate::InnerVariable {
|
||||
id: self.scope.context.get_id(),
|
||||
name: Identifier::new("self".to_string()),
|
||||
name: Identifier::new("self".into()),
|
||||
type_: Type::Circuit(circuit.as_ref().unwrap()),
|
||||
mutable: self.qualifier == FunctionQualifier::MutSelfRef,
|
||||
const_: false,
|
||||
@ -186,7 +186,7 @@ impl<'a> Function<'a> {
|
||||
}
|
||||
|
||||
pub fn is_test(&self) -> bool {
|
||||
self.annotations.iter().any(|x| x.name.name == "test")
|
||||
self.annotations.iter().any(|x| x.name.name.as_ref() == "test")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,11 +75,11 @@ fn resolve_import_package(
|
||||
) {
|
||||
match package_or_packages {
|
||||
PackageOrPackages::Package(package) => {
|
||||
package_segments.push(package.name.name.clone());
|
||||
package_segments.push(package.name.name.to_string());
|
||||
resolve_import_package_access(output, package_segments, &package.access);
|
||||
}
|
||||
PackageOrPackages::Packages(packages) => {
|
||||
package_segments.push(packages.name.name.clone());
|
||||
package_segments.push(packages.name.name.to_string());
|
||||
for access in packages.accesses.clone() {
|
||||
resolve_import_package_access(output, package_segments.clone(), &access);
|
||||
}
|
||||
@ -106,14 +106,14 @@ fn resolve_import_package_access(
|
||||
PackageAccess::Symbol(symbol) => {
|
||||
let span = symbol.symbol.span.clone();
|
||||
let symbol = if let Some(alias) = symbol.alias.as_ref() {
|
||||
ImportSymbol::Alias(symbol.symbol.name.clone(), alias.name.clone())
|
||||
ImportSymbol::Alias(symbol.symbol.name.to_string(), alias.name.to_string())
|
||||
} else {
|
||||
ImportSymbol::Direct(symbol.symbol.name.clone())
|
||||
ImportSymbol::Direct(symbol.symbol.name.to_string())
|
||||
};
|
||||
output.push((package_segments, symbol, span));
|
||||
}
|
||||
PackageAccess::Multiple(packages) => {
|
||||
package_segments.push(packages.name.name.clone());
|
||||
package_segments.push(packages.name.name.to_string());
|
||||
for subaccess in packages.accesses.iter() {
|
||||
resolve_import_package_access(output, package_segments.clone(), &subaccess);
|
||||
}
|
||||
@ -240,7 +240,7 @@ impl<'a> Program<'a> {
|
||||
assert_eq!(name.name, circuit.circuit_name.name);
|
||||
let asg_circuit = Circuit::init(scope, circuit)?;
|
||||
|
||||
scope.circuits.borrow_mut().insert(name.name.clone(), asg_circuit);
|
||||
scope.circuits.borrow_mut().insert(name.name.to_string(), asg_circuit);
|
||||
}
|
||||
|
||||
// Second pass for circuit members.
|
||||
@ -248,35 +248,35 @@ impl<'a> Program<'a> {
|
||||
assert_eq!(name.name, circuit.circuit_name.name);
|
||||
let asg_circuit = Circuit::init_member(scope, circuit)?;
|
||||
|
||||
scope.circuits.borrow_mut().insert(name.name.clone(), asg_circuit);
|
||||
scope.circuits.borrow_mut().insert(name.name.to_string(), asg_circuit);
|
||||
}
|
||||
|
||||
for (name, function) in program.functions.iter() {
|
||||
assert_eq!(name.name, function.identifier.name);
|
||||
let function = Function::init(scope, function)?;
|
||||
|
||||
scope.functions.borrow_mut().insert(name.name.clone(), function);
|
||||
scope.functions.borrow_mut().insert(name.name.to_string(), function);
|
||||
}
|
||||
|
||||
// Load concrete definitions.
|
||||
let mut functions = IndexMap::new();
|
||||
for (name, function) in program.functions.iter() {
|
||||
assert_eq!(name.name, function.identifier.name);
|
||||
let asg_function = *scope.functions.borrow().get(&name.name).unwrap();
|
||||
let asg_function = *scope.functions.borrow().get(name.name.as_ref()).unwrap();
|
||||
|
||||
asg_function.fill_from_ast(function)?;
|
||||
|
||||
functions.insert(name.name.clone(), asg_function);
|
||||
functions.insert(name.name.to_string(), asg_function);
|
||||
}
|
||||
|
||||
let mut circuits = IndexMap::new();
|
||||
for (name, circuit) in program.circuits.iter() {
|
||||
assert_eq!(name.name, circuit.circuit_name.name);
|
||||
let asg_circuit = *scope.circuits.borrow().get(&name.name).unwrap();
|
||||
let asg_circuit = *scope.circuits.borrow().get(name.name.as_ref()).unwrap();
|
||||
|
||||
asg_circuit.fill_from_ast(circuit)?;
|
||||
|
||||
circuits.insert(name.name.clone(), asg_circuit);
|
||||
circuits.insert(name.name.to_string(), asg_circuit);
|
||||
}
|
||||
|
||||
Ok(Program {
|
||||
@ -338,7 +338,7 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program {
|
||||
for (_, program) in all_programs.into_iter() {
|
||||
for (name, circuit) in program.circuits.iter() {
|
||||
let identifier = format!("{}{}", identifiers.next().unwrap(), name);
|
||||
circuit.name.borrow_mut().name = identifier.clone();
|
||||
circuit.name.borrow_mut().name = identifier.clone().into();
|
||||
all_circuits.insert(identifier, *circuit);
|
||||
}
|
||||
for (name, function) in program.functions.iter() {
|
||||
@ -347,7 +347,7 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program {
|
||||
} else {
|
||||
format!("{}{}", identifiers.next().unwrap(), name)
|
||||
};
|
||||
function.name.borrow_mut().name = identifier.clone();
|
||||
function.name.borrow_mut().name = identifier.clone().into();
|
||||
all_functions.insert(identifier, *function);
|
||||
}
|
||||
}
|
||||
@ -358,7 +358,7 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program {
|
||||
.iter()
|
||||
.map(|(module, _)| leo_ast::ImportStatement {
|
||||
package_or_packages: leo_ast::PackageOrPackages::Package(leo_ast::Package {
|
||||
name: Identifier::new(module.clone()),
|
||||
name: Identifier::new(module.clone().into()),
|
||||
access: leo_ast::PackageAccess::Star(Span::default()),
|
||||
span: Default::default(),
|
||||
}),
|
||||
|
@ -194,7 +194,7 @@ impl<'a> Scope<'a> {
|
||||
.map(|x| self.resolve_ast_type(x))
|
||||
.collect::<Result<Vec<_>, AsgConvertError>>()?,
|
||||
),
|
||||
Circuit(name) if name.name == "Self" => Type::Circuit(
|
||||
Circuit(name) if name.name.as_ref() == "Self" => Type::Circuit(
|
||||
self.resolve_circuit_self()
|
||||
.ok_or_else(|| AsgConvertError::unresolved_circuit(&name.name, &name.span))?,
|
||||
),
|
||||
|
@ -69,7 +69,7 @@ impl<'a> FromAst<'a, leo_ast::AssignStatement> for &'a Statement<'a> {
|
||||
) -> Result<Self, AsgConvertError> {
|
||||
let (name, span) = (&statement.assignee.identifier.name, &statement.assignee.identifier.span);
|
||||
|
||||
let variable = if name == "input" {
|
||||
let variable = if name.as_ref() == "input" {
|
||||
if let Some(function) = scope.resolve_current_function() {
|
||||
if !function.has_input {
|
||||
return Err(AsgConvertError::unresolved_reference(name, &span));
|
||||
@ -188,7 +188,7 @@ impl<'a> FromAst<'a, leo_ast::AssignStatement> for &'a Statement<'a> {
|
||||
let circuit = circuit;
|
||||
|
||||
let members = circuit.members.borrow();
|
||||
let member = members.get(&name.name).ok_or_else(|| {
|
||||
let member = members.get(name.name.as_ref()).ok_or_else(|| {
|
||||
AsgConvertError::unresolved_circuit_member(
|
||||
&circuit.name.borrow().name,
|
||||
&name.name,
|
||||
@ -251,7 +251,7 @@ impl<'a> Into<leo_ast::AssignStatement> for &AssignStatement<'a> {
|
||||
AssignAccess::ArrayIndex(index) => AstAssigneeAccess::ArrayIndex(index.get().into()),
|
||||
AssignAccess::Tuple(index) => AstAssigneeAccess::Tuple(
|
||||
leo_ast::PositiveNumber {
|
||||
value: index.to_string(),
|
||||
value: index.to_string().into(),
|
||||
},
|
||||
self.span.clone().unwrap_or_default(),
|
||||
),
|
||||
|
@ -106,7 +106,7 @@ impl<'a> FromAst<'a, leo_ast::DefinitionStatement> for &'a Statement<'a> {
|
||||
scope
|
||||
.variables
|
||||
.borrow_mut()
|
||||
.insert(variable.borrow().name.name.clone(), *variable);
|
||||
.insert(variable.borrow().name.name.to_string(), *variable);
|
||||
}
|
||||
|
||||
let statement = scope
|
||||
|
@ -85,7 +85,7 @@ impl<'a> FromAst<'a, leo_ast::IterationStatement> for &'a Statement<'a> {
|
||||
scope
|
||||
.variables
|
||||
.borrow_mut()
|
||||
.insert(statement.variable.name.clone(), variable);
|
||||
.insert(statement.variable.name.to_string(), variable);
|
||||
|
||||
let statement = scope.context.alloc_statement(Statement::Iteration(IterationStatement {
|
||||
parent: Cell::new(None),
|
||||
|
@ -204,7 +204,9 @@ impl<'a> Into<leo_ast::Type> for &Type<'a> {
|
||||
Integer(int_type) => leo_ast::Type::IntegerType(int_type.clone()),
|
||||
Array(type_, len) => leo_ast::Type::Array(
|
||||
Box::new(type_.as_ref().into()),
|
||||
leo_ast::ArrayDimensions(vec![leo_ast::PositiveNumber { value: len.to_string() }]),
|
||||
leo_ast::ArrayDimensions(vec![leo_ast::PositiveNumber {
|
||||
value: len.to_string().into(),
|
||||
}]),
|
||||
),
|
||||
Tuple(subtypes) => leo_ast::Type::Tuple(subtypes.iter().map(Into::into).collect()),
|
||||
Circuit(circuit) => leo_ast::Type::Circuit(circuit.name.borrow().clone()),
|
||||
|
@ -41,6 +41,9 @@ version = "1.0"
|
||||
[dependencies.thiserror]
|
||||
version = "1.0"
|
||||
|
||||
[dependencies.tendril]
|
||||
version = "0.4"
|
||||
|
||||
[dev-dependencies.criterion]
|
||||
version = "0.3"
|
||||
|
||||
|
@ -17,10 +17,12 @@
|
||||
use crate::{Identifier, Span};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tendril::StrTendril;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct Annotation {
|
||||
pub span: Span,
|
||||
pub name: Identifier,
|
||||
pub arguments: Vec<String>,
|
||||
#[serde(with = "crate::common::vec_tendril_json")]
|
||||
pub arguments: Vec<StrTendril>,
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ impl ArrayDimensions {
|
||||
///
|
||||
pub fn push_usize(&mut self, number: usize) {
|
||||
let positive_number = PositiveNumber {
|
||||
value: number.to_string(),
|
||||
value: number.to_string().into(),
|
||||
};
|
||||
|
||||
self.0.push(positive_number)
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
use crate::Span;
|
||||
use leo_input::common::Identifier as InputIdentifier;
|
||||
use tendril::StrTendril;
|
||||
|
||||
use crate::Node;
|
||||
use serde::{
|
||||
@ -41,7 +42,7 @@ use std::{
|
||||
/// to reflect the new struct instantiation.
|
||||
#[derive(Clone)]
|
||||
pub struct Identifier {
|
||||
pub name: String,
|
||||
pub name: StrTendril,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
@ -56,7 +57,7 @@ impl Node for Identifier {
|
||||
}
|
||||
|
||||
impl Identifier {
|
||||
pub fn new(name: String) -> Self {
|
||||
pub fn new(name: StrTendril) -> Self {
|
||||
Self {
|
||||
name,
|
||||
span: Span::default(),
|
||||
@ -65,24 +66,16 @@ impl Identifier {
|
||||
|
||||
pub fn new_with_span(name: &str, span: Span) -> Self {
|
||||
Self {
|
||||
name: name.to_owned(),
|
||||
name: name.into(),
|
||||
span,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_self_type(&self) -> bool {
|
||||
self.name == "Self"
|
||||
}
|
||||
|
||||
pub fn is_self(&self) -> bool {
|
||||
self.is_self_type() || self.name == "self"
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<InputIdentifier<'ast>> for Identifier {
|
||||
fn from(identifier: InputIdentifier<'ast>) -> Self {
|
||||
Self {
|
||||
name: identifier.value,
|
||||
name: identifier.value.into(),
|
||||
span: Span::from(identifier.span),
|
||||
}
|
||||
}
|
||||
@ -123,7 +116,7 @@ impl Serialize for Identifier {
|
||||
|
||||
// Load the struct elements into a BTreeMap (to preserve serialized ordering of keys).
|
||||
let mut key: BTreeMap<String, String> = BTreeMap::new();
|
||||
key.insert("name".to_string(), self.name.clone());
|
||||
key.insert("name".to_string(), self.name.to_string());
|
||||
key.insert("span".to_string(), to_json_string(&self.span)?);
|
||||
|
||||
// Convert the serialized object into a string for use as a key.
|
||||
@ -164,7 +157,10 @@ impl<'de> Deserialize<'de> for Identifier {
|
||||
None => return Err(E::custom("missing 'span' in serialized Identifier struct")),
|
||||
};
|
||||
|
||||
Ok(Identifier { name, span })
|
||||
Ok(Identifier {
|
||||
name: name.into(),
|
||||
span,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,3 +40,7 @@ pub use span::*;
|
||||
|
||||
pub mod spread_or_expression;
|
||||
pub use spread_or_expression::*;
|
||||
|
||||
pub mod tendril_json;
|
||||
|
||||
pub mod vec_tendril_json;
|
||||
|
@ -18,11 +18,13 @@ use leo_input::values::PositiveNumber as InputPositiveNumber;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use tendril::StrTendril;
|
||||
|
||||
/// A number string guaranteed to be positive by the pest grammar.
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct PositiveNumber {
|
||||
pub value: String,
|
||||
#[serde(with = "crate::common::tendril_json")]
|
||||
pub value: StrTendril,
|
||||
}
|
||||
|
||||
impl PositiveNumber {
|
||||
@ -30,14 +32,16 @@ impl PositiveNumber {
|
||||
/// Returns `true` if this number is zero.
|
||||
///
|
||||
pub fn is_zero(&self) -> bool {
|
||||
self.value.eq("0")
|
||||
self.value.as_ref().eq("0")
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new [`PositiveNumber`] from an [`InputPositiveNumber`] in a Leo input file.
|
||||
impl<'ast> From<InputPositiveNumber<'ast>> for PositiveNumber {
|
||||
fn from(array: InputPositiveNumber<'ast>) -> Self {
|
||||
Self { value: array.value }
|
||||
Self {
|
||||
value: array.value.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,9 +14,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use std::{fmt, rc::Rc};
|
||||
use std::{fmt, sync::Arc};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tendril::StrTendril;
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)]
|
||||
pub struct Span {
|
||||
@ -24,7 +25,9 @@ pub struct Span {
|
||||
pub line_stop: usize,
|
||||
pub col_start: usize,
|
||||
pub col_stop: usize,
|
||||
pub path: Rc<String>,
|
||||
pub path: Arc<String>,
|
||||
#[serde(with = "crate::common::tendril_json")]
|
||||
pub content: StrTendril,
|
||||
}
|
||||
|
||||
impl fmt::Display for Span {
|
||||
@ -51,7 +54,8 @@ impl<'ast> From<pest::Span<'ast>> for Span {
|
||||
line_stop: end.0,
|
||||
col_start: start.1,
|
||||
col_stop: end.1,
|
||||
path: Rc::new(String::new()),
|
||||
path: Arc::new(String::new()),
|
||||
content: span.as_str().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -76,22 +80,40 @@ impl std::ops::Add for Span {
|
||||
col_start: self.col_start.min(other.col_start),
|
||||
col_stop: self.col_stop.max(other.col_stop),
|
||||
path: self.path,
|
||||
}
|
||||
} else if self.line_start < other.line_stop {
|
||||
Span {
|
||||
line_start: self.line_start,
|
||||
line_stop: other.line_stop,
|
||||
col_start: self.col_start,
|
||||
col_stop: other.col_stop,
|
||||
path: self.path,
|
||||
content: self.content,
|
||||
}
|
||||
} else {
|
||||
Span {
|
||||
line_start: other.line_start,
|
||||
line_stop: self.line_stop,
|
||||
col_start: other.col_start,
|
||||
col_stop: self.col_stop,
|
||||
path: self.path,
|
||||
let mut new_content = vec![];
|
||||
let self_lines = self.content.lines().collect::<Vec<_>>();
|
||||
let other_lines = other.content.lines().collect::<Vec<_>>();
|
||||
for line in self.line_start.min(other.line_start)..self.line_stop.max(other.line_stop) + 1 {
|
||||
if line >= self.line_start && line <= self.line_stop {
|
||||
new_content.push(self_lines.get(line - self.line_start).copied().unwrap_or_default());
|
||||
} else if line >= other.line_start && line <= other.line_stop {
|
||||
new_content.push(other_lines.get(line - other.line_start).copied().unwrap_or_default());
|
||||
} else if new_content.last().map(|x| *x != "...").unwrap_or(true) {
|
||||
new_content.push("...");
|
||||
}
|
||||
}
|
||||
let new_content = new_content.join("\n").into();
|
||||
if self.line_start < other.line_stop {
|
||||
Span {
|
||||
line_start: self.line_start,
|
||||
line_stop: other.line_stop,
|
||||
col_start: self.col_start,
|
||||
col_stop: other.col_stop,
|
||||
path: self.path,
|
||||
content: new_content,
|
||||
}
|
||||
} else {
|
||||
Span {
|
||||
line_start: other.line_start,
|
||||
line_stop: self.line_stop,
|
||||
col_start: other.col_start,
|
||||
col_stop: self.col_stop,
|
||||
path: self.path,
|
||||
content: new_content,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
26
ast/src/common/tendril_json.rs
Normal file
26
ast/src/common/tendril_json.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright (C) 2019-2021 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use serde::{Deserialize, Deserializer, Serializer};
|
||||
use tendril::StrTendril;
|
||||
|
||||
pub fn serialize<S: Serializer>(tendril: &StrTendril, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
serializer.serialize_str(&tendril[..])
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<StrTendril, D::Error> {
|
||||
Ok(String::deserialize(deserializer)?.into())
|
||||
}
|
34
ast/src/common/vec_tendril_json.rs
Normal file
34
ast/src/common/vec_tendril_json.rs
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright (C) 2019-2021 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use tendril::StrTendril;
|
||||
|
||||
#[allow(clippy::ptr_arg)]
|
||||
pub fn serialize<S: Serializer>(tendril: &Vec<StrTendril>, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
tendril
|
||||
.iter()
|
||||
.map(|x| x.as_ref())
|
||||
.collect::<Vec<_>>()
|
||||
.serialize(serializer)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<StrTendril>, D::Error> {
|
||||
Ok(Vec::<String>::deserialize(deserializer)?
|
||||
.into_iter()
|
||||
.map(|x| x.into())
|
||||
.collect())
|
||||
}
|
@ -16,12 +16,12 @@
|
||||
|
||||
use crate::{LeoError, Span};
|
||||
|
||||
use std::fmt;
|
||||
use std::{fmt, sync::Arc};
|
||||
|
||||
pub const INDENT: &str = " ";
|
||||
|
||||
/// Formatted compiler error type
|
||||
/// --> file.leo 2:8
|
||||
/// --> file.leo: 2:8
|
||||
/// |
|
||||
/// 2 | let a = x;
|
||||
/// | ^
|
||||
@ -29,60 +29,30 @@ pub const INDENT: &str = " ";
|
||||
/// = undefined value `x`
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct FormattedError {
|
||||
/// File path where error occurred
|
||||
pub path: Option<String>,
|
||||
/// Line start number
|
||||
pub line_start: usize,
|
||||
/// Line end number
|
||||
pub line_stop: usize,
|
||||
/// Starting column
|
||||
pub start: usize,
|
||||
/// Ending column
|
||||
pub end: usize,
|
||||
/// Text of errored lines
|
||||
pub text: Option<Vec<String>>,
|
||||
/// Error explanation
|
||||
pub col_start: usize,
|
||||
pub col_stop: usize,
|
||||
pub path: Arc<String>,
|
||||
pub content: String,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
impl FormattedError {
|
||||
pub fn new_from_span(message: String, span: &Span) -> Self {
|
||||
Self {
|
||||
path: None,
|
||||
line_start: span.line_start,
|
||||
line_stop: span.line_stop,
|
||||
start: span.col_start,
|
||||
end: span.col_stop,
|
||||
text: None,
|
||||
col_start: span.col_start,
|
||||
col_stop: span.col_stop,
|
||||
path: span.path.clone(),
|
||||
content: span.content.to_string(),
|
||||
message,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LeoError for FormattedError {
|
||||
fn set_path(&mut self, path: &str, content: &[String]) {
|
||||
self.path = Some(path.to_string());
|
||||
if self.line_stop - 1 > content.len() {
|
||||
self.text = Some(vec!["corrupt file".to_string()]);
|
||||
return;
|
||||
}
|
||||
assert!(self.line_stop >= self.line_start);
|
||||
// if self.line_stop == self.line_start {
|
||||
// self.text = Some(vec![content[self.line_start - 1][self.start - 1..self.end - 1].to_string()]);
|
||||
// } else {
|
||||
self.text = Some(
|
||||
content[self.line_start - 1..self.line_stop]
|
||||
.iter()
|
||||
.map(|x| x.to_string())
|
||||
.collect(),
|
||||
);
|
||||
// }
|
||||
}
|
||||
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
self.path.as_deref()
|
||||
}
|
||||
}
|
||||
impl LeoError for FormattedError {}
|
||||
|
||||
fn underline(mut start: usize, mut end: usize) -> String {
|
||||
if start > end {
|
||||
@ -105,29 +75,26 @@ fn underline(mut start: usize, mut end: usize) -> String {
|
||||
|
||||
impl fmt::Display for FormattedError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let path = self.path.as_ref().map(|path| format!("{}:", path)).unwrap_or_default();
|
||||
let underline = underline(self.start - 1, self.end - 1);
|
||||
let underline = underline(self.col_start - 1, self.col_stop - 1);
|
||||
|
||||
write!(
|
||||
f,
|
||||
"{indent }--> {path} {line_start}:{start}\n\
|
||||
"{indent }--> {path}: {line_start}:{start}\n\
|
||||
{indent } |\n",
|
||||
indent = INDENT,
|
||||
path = path,
|
||||
path = &*self.path,
|
||||
line_start = self.line_start,
|
||||
start = self.start,
|
||||
start = self.col_start,
|
||||
)?;
|
||||
|
||||
if let Some(lines) = &self.text {
|
||||
for (line_no, line) in lines.iter().enumerate() {
|
||||
writeln!(
|
||||
f,
|
||||
"{line_no:width$} | {text}",
|
||||
width = INDENT.len(),
|
||||
line_no = self.line_start + line_no,
|
||||
text = line,
|
||||
)?;
|
||||
}
|
||||
for (line_no, line) in self.content.lines().enumerate() {
|
||||
writeln!(
|
||||
f,
|
||||
"{line_no:width$} | {text}",
|
||||
width = INDENT.len(),
|
||||
line_no = self.line_start + line_no,
|
||||
text = line,
|
||||
)?;
|
||||
}
|
||||
|
||||
write!(
|
||||
@ -151,12 +118,12 @@ impl std::error::Error for FormattedError {
|
||||
#[test]
|
||||
fn test_error() {
|
||||
let err = FormattedError {
|
||||
path: Some("file.leo".to_string()),
|
||||
path: std::sync::Arc::new("file.leo".to_string()),
|
||||
line_start: 2,
|
||||
line_stop: 2,
|
||||
start: 8,
|
||||
end: 9,
|
||||
text: Some(vec!["let a = x;".to_string()]),
|
||||
col_start: 8,
|
||||
col_stop: 9,
|
||||
content: "let a = x;".into(),
|
||||
message: "undefined value `x`".to_string(),
|
||||
};
|
||||
|
||||
|
@ -17,8 +17,4 @@
|
||||
pub mod error;
|
||||
pub use error::*;
|
||||
|
||||
pub trait LeoError {
|
||||
fn get_path(&self) -> Option<&str>;
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]);
|
||||
}
|
||||
pub trait LeoError {}
|
||||
|
@ -14,18 +14,24 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use tendril::StrTendril;
|
||||
|
||||
use super::*;
|
||||
use crate::GroupTuple;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum ValueExpression {
|
||||
// todo: deserialize values here
|
||||
Address(String, Span),
|
||||
Boolean(String, Span),
|
||||
Field(String, Span),
|
||||
Address(#[serde(with = "crate::common::tendril_json")] StrTendril, Span),
|
||||
Boolean(#[serde(with = "crate::common::tendril_json")] StrTendril, Span),
|
||||
Field(#[serde(with = "crate::common::tendril_json")] StrTendril, Span),
|
||||
Group(Box<GroupValue>),
|
||||
Implicit(String, Span),
|
||||
Integer(IntegerType, String, Span),
|
||||
Implicit(#[serde(with = "crate::common::tendril_json")] StrTendril, Span),
|
||||
Integer(
|
||||
IntegerType,
|
||||
#[serde(with = "crate::common::tendril_json")] StrTendril,
|
||||
Span,
|
||||
),
|
||||
}
|
||||
|
||||
impl fmt::Display for ValueExpression {
|
||||
|
@ -25,10 +25,11 @@ use leo_input::values::{
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use tendril::StrTendril;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum GroupCoordinate {
|
||||
Number(String, Span),
|
||||
Number(#[serde(with = "crate::common::tendril_json")] StrTendril, Span),
|
||||
SignHigh,
|
||||
SignLow,
|
||||
Inferred,
|
||||
@ -61,7 +62,7 @@ impl<'ast> From<InputNumberValue<'ast>> for GroupCoordinate {
|
||||
let value = number.to_string();
|
||||
let span = Span::from(number.span().clone());
|
||||
|
||||
GroupCoordinate::Number(value, span)
|
||||
GroupCoordinate::Number(value.into(), span)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,10 +23,11 @@ use leo_input::values::{
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use tendril::StrTendril;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum GroupValue {
|
||||
Single(String, Span),
|
||||
Single(#[serde(with = "crate::common::tendril_json")] StrTendril, Span),
|
||||
Tuple(GroupTuple),
|
||||
}
|
||||
|
||||
@ -51,7 +52,7 @@ impl<'ast> From<InputGroupValue<'ast>> for GroupValue {
|
||||
let span = Span::from(ast_group.span);
|
||||
|
||||
match ast_group.value {
|
||||
InputGroupRepresentation::Single(number) => GroupValue::Single(number.to_string(), span),
|
||||
InputGroupRepresentation::Single(number) => GroupValue::Single(number.to_string().into(), span),
|
||||
InputGroupRepresentation::Tuple(tuple) => GroupValue::Tuple(GroupTuple::from(tuple)),
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ impl ImportSymbol {
|
||||
pub fn star(span: &Span) -> Self {
|
||||
Self {
|
||||
symbol: Identifier {
|
||||
name: "*".to_string(),
|
||||
name: "*".into(),
|
||||
span: span.clone(),
|
||||
},
|
||||
alias: None,
|
||||
@ -60,6 +60,6 @@ impl ImportSymbol {
|
||||
}
|
||||
|
||||
pub fn is_star(&self) -> bool {
|
||||
self.symbol.name.eq("*")
|
||||
self.symbol.name.as_ref().eq("*")
|
||||
}
|
||||
}
|
||||
|
@ -96,13 +96,13 @@ impl Input {
|
||||
|
||||
/// Returns the main function input value with the given `name`.
|
||||
#[allow(clippy::ptr_arg)]
|
||||
pub fn get(&self, name: &String) -> Option<Option<InputValue>> {
|
||||
pub fn get(&self, name: &str) -> Option<Option<InputValue>> {
|
||||
self.program_input.get(name)
|
||||
}
|
||||
|
||||
/// Returns the constant input value with the given `name`.
|
||||
#[allow(clippy::ptr_arg)]
|
||||
pub fn get_constant(&self, name: &String) -> Option<Option<InputValue>> {
|
||||
pub fn get_constant(&self, name: &str) -> Option<Option<InputValue>> {
|
||||
self.program_input.get_constant(name)
|
||||
}
|
||||
|
||||
|
@ -74,12 +74,12 @@ impl ProgramInput {
|
||||
|
||||
/// Returns the main function input value with the given `name`
|
||||
#[allow(clippy::ptr_arg)]
|
||||
pub fn get(&self, name: &String) -> Option<Option<InputValue>> {
|
||||
pub fn get(&self, name: &str) -> Option<Option<InputValue>> {
|
||||
self.main.get(name)
|
||||
}
|
||||
|
||||
#[allow(clippy::ptr_arg)]
|
||||
pub fn get_constant(&self, name: &String) -> Option<Option<InputValue>> {
|
||||
pub fn get_constant(&self, name: &str) -> Option<Option<InputValue>> {
|
||||
self.constants.get(name)
|
||||
}
|
||||
|
||||
|
@ -171,7 +171,7 @@ impl Canonicalizer {
|
||||
|
||||
Expression::CircuitInit(circuit_init) => {
|
||||
let mut name = circuit_init.name.clone();
|
||||
if name.name == *"Self" {
|
||||
if name.name.as_ref() == "Self" {
|
||||
name = self.circuit_name.as_ref().unwrap().clone();
|
||||
}
|
||||
|
||||
|
@ -18,10 +18,11 @@ use crate::{Expression, Node, Span};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use tendril::StrTendril;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
||||
pub enum FormattedStringPart {
|
||||
Const(String),
|
||||
Const(#[serde(with = "crate::common::tendril_json")] StrTendril),
|
||||
Container,
|
||||
}
|
||||
|
||||
|
@ -24,10 +24,9 @@ use crate::{
|
||||
OutputBytes,
|
||||
OutputFile,
|
||||
};
|
||||
use indexmap::IndexMap;
|
||||
pub use leo_asg::{new_context, AsgContext as Context, AsgContext};
|
||||
use leo_asg::{Asg, AsgPass, FormattedError, Program as AsgProgram};
|
||||
use leo_ast::{Input, LeoError, MainInput, Program as AstProgram};
|
||||
use leo_ast::{Input, MainInput, Program as AstProgram};
|
||||
use leo_input::LeoInputParser;
|
||||
use leo_package::inputs::InputPairs;
|
||||
use leo_parser::parse_ast;
|
||||
@ -39,11 +38,9 @@ use snarkvm_r1cs::{ConstraintSynthesizer, ConstraintSystem, SynthesisError};
|
||||
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
fs,
|
||||
marker::PhantomData,
|
||||
path::{Path, PathBuf},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
thread_local! {
|
||||
@ -68,7 +65,6 @@ pub struct Compiler<'a, F: PrimeField, G: GroupType<F>> {
|
||||
program_input: Input,
|
||||
context: AsgContext<'a>,
|
||||
asg: Option<AsgProgram<'a>>,
|
||||
file_contents: RefCell<IndexMap<String, Rc<Vec<String>>>>,
|
||||
options: CompilerOptions,
|
||||
_engine: PhantomData<F>,
|
||||
_group: PhantomData<G>,
|
||||
@ -93,7 +89,6 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
asg: None,
|
||||
context,
|
||||
options: CompilerOptions::default(),
|
||||
file_contents: RefCell::new(IndexMap::new()),
|
||||
_engine: PhantomData,
|
||||
_group: PhantomData,
|
||||
}
|
||||
@ -200,20 +195,6 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn resolve_content(&self, path: &str) -> Result<Rc<Vec<String>>, CompilerError> {
|
||||
let mut file_contents = self.file_contents.borrow_mut();
|
||||
if file_contents.contains_key(path) {
|
||||
// using this pattern because of mutable reference in branch below
|
||||
Ok(file_contents.get(path).unwrap().clone())
|
||||
} else {
|
||||
let content = fs::read_to_string(path).map_err(|e| CompilerError::FileReadError(PathBuf::from(path), e))?;
|
||||
|
||||
let content = Rc::new(content.lines().map(|x| x.to_string()).collect::<Vec<String>>());
|
||||
file_contents.insert(path.to_string(), content);
|
||||
Ok(file_contents.get(path).unwrap().clone())
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Parses and stores the main program file, constructs a syntax tree, and generates a program.
|
||||
///
|
||||
@ -224,31 +205,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
let content = fs::read_to_string(&self.main_file_path)
|
||||
.map_err(|e| CompilerError::FileReadError(self.main_file_path.clone(), e))?;
|
||||
|
||||
self.parse_program_from_string(&content).map_err(|mut error| {
|
||||
// Return a formatted error with file path and code text.
|
||||
|
||||
let path = match error.get_path().map(|x| x.to_string()) {
|
||||
// Get the file path if it exists
|
||||
Some(path) => path,
|
||||
|
||||
// If a file path does not exist, then insert the main file path.
|
||||
None => match self.main_file_path.clone().into_os_string().into_string() {
|
||||
Err(e) => return CompilerError::FileStringError(e),
|
||||
Ok(path) => path,
|
||||
},
|
||||
};
|
||||
|
||||
// Resolve the code text using the file path.
|
||||
let content = match self.resolve_content(&path) {
|
||||
Err(e) => return e,
|
||||
Ok(x) => x,
|
||||
};
|
||||
|
||||
// Update the formatted error.
|
||||
error.set_path(&path, &content[..]);
|
||||
|
||||
error
|
||||
})
|
||||
self.parse_program_from_string(&content)
|
||||
}
|
||||
|
||||
///
|
||||
@ -257,11 +214,6 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
///
|
||||
pub fn parse_program_from_string(&mut self, program_string: &str) -> Result<(), CompilerError> {
|
||||
// Use the parser to construct the abstract syntax tree (ast).
|
||||
let lines = program_string.lines().map(|x| x.to_string()).collect();
|
||||
self.file_contents.borrow_mut().insert(
|
||||
self.main_file_path.to_str().map(|x| x.to_string()).unwrap_or_default(),
|
||||
Rc::new(lines),
|
||||
);
|
||||
|
||||
let mut ast = parse_ast(self.main_file_path.to_str().unwrap_or_default(), program_string)?;
|
||||
// Preform compiler optimization via canonicalizing AST if its enabled.
|
||||
@ -313,28 +265,14 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
/// Synthesizes the circuit with program input to verify correctness.
|
||||
///
|
||||
pub fn compile_constraints<CS: ConstraintSystem<F>>(&self, cs: &mut CS) -> Result<OutputBytes, CompilerError> {
|
||||
generate_constraints::<F, G, CS>(cs, &self.asg.as_ref().unwrap(), &self.program_input).map_err(|mut error| {
|
||||
if let Some(path) = error.get_path().map(|x| x.to_string()) {
|
||||
let content = match self.resolve_content(&path) {
|
||||
Err(e) => return e,
|
||||
Ok(x) => x,
|
||||
};
|
||||
error.set_path(&path, &content[..]);
|
||||
}
|
||||
error
|
||||
})
|
||||
generate_constraints::<F, G, CS>(cs, &self.asg.as_ref().unwrap(), &self.program_input)
|
||||
}
|
||||
|
||||
///
|
||||
/// Synthesizes the circuit for test functions with program input.
|
||||
///
|
||||
pub fn compile_test_constraints(self, input_pairs: InputPairs) -> Result<(u32, u32), CompilerError> {
|
||||
generate_test_constraints::<F, G>(
|
||||
&self.asg.as_ref().unwrap(),
|
||||
input_pairs,
|
||||
&self.main_file_path,
|
||||
&self.output_directory,
|
||||
)
|
||||
generate_test_constraints::<F, G>(&self.asg.as_ref().unwrap(), input_pairs, &self.output_directory)
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{errors::CompilerError, ConstrainedProgram, GroupType, OutputBytes, OutputFile};
|
||||
use leo_asg::Program;
|
||||
use leo_ast::{Input, LeoError};
|
||||
use leo_ast::Input;
|
||||
use leo_input::LeoInputParser;
|
||||
use leo_package::inputs::InputPairs;
|
||||
|
||||
@ -50,7 +50,6 @@ pub fn generate_constraints<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSy
|
||||
pub fn generate_test_constraints<'a, F: PrimeField, G: GroupType<F>>(
|
||||
program: &Program<'a>,
|
||||
input: InputPairs,
|
||||
main_file_path: &Path,
|
||||
output_directory: &Path,
|
||||
) -> Result<(u32, u32), CompilerError> {
|
||||
let mut resolved_program = ConstrainedProgram::<F, G>::new(program.clone());
|
||||
@ -78,7 +77,7 @@ pub fn generate_test_constraints<'a, F: PrimeField, G: GroupType<F>>(
|
||||
let input_file = function
|
||||
.annotations
|
||||
.iter()
|
||||
.find(|x| x.name.name == "test")
|
||||
.find(|x| x.name.name.as_ref() == "test")
|
||||
.unwrap()
|
||||
.arguments
|
||||
.get(0);
|
||||
@ -87,11 +86,11 @@ pub fn generate_test_constraints<'a, F: PrimeField, G: GroupType<F>>(
|
||||
Some(file_id) => {
|
||||
let file_name = file_id.clone();
|
||||
|
||||
output_file_name = file_name.clone();
|
||||
output_file_name = file_name.to_string();
|
||||
|
||||
match input.pairs.get(&file_name) {
|
||||
match input.pairs.get(file_name.as_ref()) {
|
||||
Some(pair) => pair.to_owned(),
|
||||
None => return Err(CompilerError::InvalidTestContext(file_name)),
|
||||
None => return Err(CompilerError::InvalidTestContext(file_name.to_string())),
|
||||
}
|
||||
}
|
||||
None => default.ok_or(CompilerError::NoTestInput)?,
|
||||
@ -135,8 +134,7 @@ pub fn generate_test_constraints<'a, F: PrimeField, G: GroupType<F>>(
|
||||
}
|
||||
(false, _) => {
|
||||
// Set file location of error
|
||||
let mut error = result.unwrap_err();
|
||||
error.set_path(main_file_path.to_str().unwrap_or_default(), &[]);
|
||||
let error = result.unwrap_err();
|
||||
|
||||
tracing::error!("{} failed due to error\n\n{}\n", full_test_name, error);
|
||||
|
||||
|
@ -82,30 +82,4 @@ pub enum CompilerError {
|
||||
CanonicalizeError(#[from] CanonicalizeError),
|
||||
}
|
||||
|
||||
impl LeoError for CompilerError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
CompilerError::SyntaxError(error) => error.get_path(),
|
||||
CompilerError::ImportError(error) => error.get_path(),
|
||||
CompilerError::ImportParserError(error) => error.get_path(),
|
||||
CompilerError::InputParserError(error) => error.get_path(),
|
||||
CompilerError::FunctionError(error) => error.get_path(),
|
||||
CompilerError::OutputStringError(error) => error.get_path(),
|
||||
CompilerError::AsgConvertError(error) => error.get_path(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
CompilerError::SyntaxError(error) => error.set_path(path, contents),
|
||||
CompilerError::ImportError(error) => error.set_path(path, contents),
|
||||
CompilerError::ImportParserError(error) => error.set_path(path, contents),
|
||||
CompilerError::InputParserError(error) => error.set_path(path, contents),
|
||||
CompilerError::FunctionError(error) => error.set_path(path, contents),
|
||||
CompilerError::OutputStringError(error) => error.set_path(path, contents),
|
||||
CompilerError::AsgConvertError(error) => error.set_path(path, contents),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for CompilerError {}
|
||||
|
@ -26,21 +26,7 @@ pub enum ConsoleError {
|
||||
Expression(#[from] ExpressionError),
|
||||
}
|
||||
|
||||
impl LeoError for ConsoleError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
ConsoleError::Error(error) => error.get_path(),
|
||||
ConsoleError::Expression(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
ConsoleError::Error(error) => error.set_path(path, contents),
|
||||
ConsoleError::Expression(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for ConsoleError {}
|
||||
|
||||
impl ConsoleError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -45,33 +45,7 @@ pub enum ExpressionError {
|
||||
ValueError(#[from] ValueError),
|
||||
}
|
||||
|
||||
impl LeoError for ExpressionError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
ExpressionError::AddressError(error) => error.get_path(),
|
||||
ExpressionError::BooleanError(error) => error.get_path(),
|
||||
ExpressionError::Error(error) => error.get_path(),
|
||||
ExpressionError::FieldError(error) => error.get_path(),
|
||||
ExpressionError::FunctionError(error) => error.get_path(),
|
||||
ExpressionError::GroupError(error) => error.get_path(),
|
||||
ExpressionError::IntegerError(error) => error.get_path(),
|
||||
ExpressionError::ValueError(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
ExpressionError::AddressError(error) => error.set_path(path, contents),
|
||||
ExpressionError::BooleanError(error) => error.set_path(path, contents),
|
||||
ExpressionError::Error(error) => error.set_path(path, contents),
|
||||
ExpressionError::FieldError(error) => error.set_path(path, contents),
|
||||
ExpressionError::FunctionError(error) => error.set_path(path, contents),
|
||||
ExpressionError::GroupError(error) => error.set_path(path, contents),
|
||||
ExpressionError::IntegerError(error) => error.set_path(path, contents),
|
||||
ExpressionError::ValueError(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for ExpressionError {}
|
||||
|
||||
impl ExpressionError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -64,39 +64,7 @@ pub enum FunctionError {
|
||||
ImportASGError(#[from] AsgConvertError),
|
||||
}
|
||||
|
||||
impl LeoError for FunctionError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
FunctionError::AddressError(error) => error.get_path(),
|
||||
FunctionError::BooleanError(error) => error.get_path(),
|
||||
FunctionError::ExpressionError(error) => error.get_path(),
|
||||
FunctionError::Error(error) => error.get_path(),
|
||||
FunctionError::FieldError(error) => error.get_path(),
|
||||
FunctionError::GroupError(error) => error.get_path(),
|
||||
FunctionError::IntegerError(error) => error.get_path(),
|
||||
FunctionError::OutputStringError(error) => error.get_path(),
|
||||
FunctionError::StatementError(error) => error.get_path(),
|
||||
FunctionError::ValueError(error) => error.get_path(),
|
||||
FunctionError::ImportASGError(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
FunctionError::AddressError(error) => error.set_path(path, contents),
|
||||
FunctionError::BooleanError(error) => error.set_path(path, contents),
|
||||
FunctionError::ExpressionError(error) => error.set_path(path, contents),
|
||||
FunctionError::Error(error) => error.set_path(path, contents),
|
||||
FunctionError::FieldError(error) => error.set_path(path, contents),
|
||||
FunctionError::GroupError(error) => error.set_path(path, contents),
|
||||
FunctionError::IntegerError(error) => error.set_path(path, contents),
|
||||
FunctionError::OutputStringError(error) => error.set_path(path, contents),
|
||||
FunctionError::StatementError(error) => error.set_path(path, contents),
|
||||
FunctionError::ValueError(error) => error.set_path(path, contents),
|
||||
FunctionError::ImportASGError(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for FunctionError {}
|
||||
|
||||
impl FunctionError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -22,19 +22,7 @@ pub enum ImportError {
|
||||
Error(#[from] FormattedError),
|
||||
}
|
||||
|
||||
impl LeoError for ImportError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
ImportError::Error(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
ImportError::Error(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for ImportError {}
|
||||
|
||||
impl ImportError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -30,23 +30,7 @@ pub enum OutputBytesError {
|
||||
AsgConvertError(#[from] AsgConvertError),
|
||||
}
|
||||
|
||||
impl LeoError for OutputBytesError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
OutputBytesError::Error(error) => error.get_path(),
|
||||
OutputBytesError::ValueError(error) => error.get_path(),
|
||||
OutputBytesError::AsgConvertError(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
OutputBytesError::Error(error) => error.set_path(path, contents),
|
||||
OutputBytesError::ValueError(error) => error.set_path(path, contents),
|
||||
OutputBytesError::AsgConvertError(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for OutputBytesError {}
|
||||
|
||||
impl OutputBytesError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -42,31 +42,7 @@ pub enum StatementError {
|
||||
ValueError(#[from] ValueError),
|
||||
}
|
||||
|
||||
impl LeoError for StatementError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
StatementError::AddressError(error) => error.get_path(),
|
||||
StatementError::BooleanError(error) => error.get_path(),
|
||||
StatementError::Error(error) => error.get_path(),
|
||||
StatementError::ExpressionError(error) => error.get_path(),
|
||||
StatementError::IntegerError(error) => error.get_path(),
|
||||
StatementError::MacroError(error) => error.get_path(),
|
||||
StatementError::ValueError(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
StatementError::AddressError(error) => error.set_path(path, contents),
|
||||
StatementError::BooleanError(error) => error.set_path(path, contents),
|
||||
StatementError::Error(error) => error.set_path(path, contents),
|
||||
StatementError::ExpressionError(error) => error.set_path(path, contents),
|
||||
StatementError::IntegerError(error) => error.set_path(path, contents),
|
||||
StatementError::MacroError(error) => error.set_path(path, contents),
|
||||
StatementError::ValueError(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for StatementError {}
|
||||
|
||||
impl StatementError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -24,19 +24,7 @@ pub enum AddressError {
|
||||
Error(#[from] FormattedError),
|
||||
}
|
||||
|
||||
impl LeoError for AddressError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
AddressError::Error(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
AddressError::Error(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for AddressError {}
|
||||
|
||||
impl AddressError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -23,19 +23,7 @@ pub enum BooleanError {
|
||||
Error(#[from] FormattedError),
|
||||
}
|
||||
|
||||
impl LeoError for BooleanError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
BooleanError::Error(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
BooleanError::Error(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for BooleanError {}
|
||||
|
||||
impl BooleanError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -23,19 +23,7 @@ pub enum FieldError {
|
||||
Error(#[from] FormattedError),
|
||||
}
|
||||
|
||||
impl LeoError for FieldError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
FieldError::Error(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
FieldError::Error(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for FieldError {}
|
||||
|
||||
impl FieldError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -23,19 +23,7 @@ pub enum GroupError {
|
||||
Error(#[from] FormattedError),
|
||||
}
|
||||
|
||||
impl LeoError for GroupError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
GroupError::Error(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
GroupError::Error(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for GroupError {}
|
||||
|
||||
impl GroupError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -25,19 +25,7 @@ pub enum IntegerError {
|
||||
Error(#[from] FormattedError),
|
||||
}
|
||||
|
||||
impl LeoError for IntegerError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
IntegerError::Error(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
IntegerError::Error(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for IntegerError {}
|
||||
|
||||
impl IntegerError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -38,29 +38,7 @@ pub enum ValueError {
|
||||
IntegerError(#[from] IntegerError),
|
||||
}
|
||||
|
||||
impl LeoError for ValueError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
ValueError::AddressError(error) => error.get_path(),
|
||||
ValueError::BooleanError(error) => error.get_path(),
|
||||
ValueError::Error(error) => error.get_path(),
|
||||
ValueError::FieldError(error) => error.get_path(),
|
||||
ValueError::GroupError(error) => error.get_path(),
|
||||
ValueError::IntegerError(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
ValueError::AddressError(error) => error.set_path(path, contents),
|
||||
ValueError::BooleanError(error) => error.set_path(path, contents),
|
||||
ValueError::Error(error) => error.set_path(path, contents),
|
||||
ValueError::FieldError(error) => error.set_path(path, contents),
|
||||
ValueError::GroupError(error) => error.set_path(path, contents),
|
||||
ValueError::IntegerError(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for ValueError {}
|
||||
|
||||
impl ValueError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -42,7 +42,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
// type checking is already done in asg
|
||||
for (name, inner) in expr.values.iter() {
|
||||
let target = members
|
||||
.get(&name.name)
|
||||
.get(name.name.as_ref())
|
||||
.expect("illegal name in asg circuit init expression");
|
||||
match target {
|
||||
CircuitMember::Variable(_type_) => {
|
||||
|
@ -41,7 +41,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, ExpressionError> {
|
||||
Ok(match value {
|
||||
ConstValue::Address(value) => ConstrainedValue::Address(Address::constant(value.clone(), span)?),
|
||||
ConstValue::Address(value) => ConstrainedValue::Address(Address::constant(value.to_string(), span)?),
|
||||
ConstValue::Boolean(value) => ConstrainedValue::Boolean(Boolean::Constant(*value)),
|
||||
ConstValue::Field(value) => ConstrainedValue::Field(FieldType::constant(value.to_string(), span)?),
|
||||
ConstValue::Group(value) => ConstrainedValue::Group(G::constant(value, span)?),
|
||||
|
@ -38,19 +38,19 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
// Create an identifier for each input variable
|
||||
|
||||
let registers_name = Identifier {
|
||||
name: REGISTERS_VARIABLE_NAME.to_string(),
|
||||
name: REGISTERS_VARIABLE_NAME.into(),
|
||||
span: span.clone(),
|
||||
};
|
||||
let record_name = Identifier {
|
||||
name: RECORD_VARIABLE_NAME.to_string(),
|
||||
name: RECORD_VARIABLE_NAME.into(),
|
||||
span: span.clone(),
|
||||
};
|
||||
let state_name = Identifier {
|
||||
name: STATE_VARIABLE_NAME.to_string(),
|
||||
name: STATE_VARIABLE_NAME.into(),
|
||||
span: span.clone(),
|
||||
};
|
||||
let state_leaf_name = Identifier {
|
||||
name: STATE_LEAF_VARIABLE_NAME.to_string(),
|
||||
name: STATE_LEAF_VARIABLE_NAME.into(),
|
||||
span: span.clone(),
|
||||
};
|
||||
|
||||
@ -73,7 +73,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
let mut members = Vec::with_capacity(sections.len());
|
||||
|
||||
for (name, values) in sections {
|
||||
let sub_circuit = match expected_type.members.borrow().get(&name.name) {
|
||||
let sub_circuit = match expected_type.members.borrow().get(name.name.as_ref()) {
|
||||
Some(CircuitMember::Variable(Type::Circuit(circuit))) => *circuit,
|
||||
_ => panic!("illegal input type definition from asg"),
|
||||
};
|
||||
|
@ -36,7 +36,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
// Allocate each section definition as a circuit member value
|
||||
for (parameter, option) in section.into_iter() {
|
||||
let section_members = expected_type.members.borrow();
|
||||
let expected_type = match section_members.get(¶meter.variable.name) {
|
||||
let expected_type = match section_members.get(parameter.variable.name.as_ref()) {
|
||||
Some(CircuitMember::Variable(inner)) => inner,
|
||||
_ => continue, // present, but unused
|
||||
};
|
||||
|
@ -62,11 +62,15 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
let input_variable = input_variable.get().borrow();
|
||||
let name = input_variable.name.name.clone();
|
||||
|
||||
let input_value = match (input_variable.const_, input.get(&name), input.get_constant(&name)) {
|
||||
let input_value = match (
|
||||
input_variable.const_,
|
||||
input.get(&name),
|
||||
input.get_constant(name.as_ref()),
|
||||
) {
|
||||
// If variable is in both [main] and [constants] sections - error.
|
||||
(_, Some(_), Some(_)) => {
|
||||
return Err(FunctionError::double_input_declaration(
|
||||
name.clone(),
|
||||
name.to_string(),
|
||||
&function.span.clone().unwrap_or_default(),
|
||||
));
|
||||
}
|
||||
@ -89,21 +93,21 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
// Function argument is const, input is not.
|
||||
(true, Some(_), None) => {
|
||||
return Err(FunctionError::expected_const_input(
|
||||
name.clone(),
|
||||
name.to_string(),
|
||||
&function.span.clone().unwrap_or_default(),
|
||||
));
|
||||
}
|
||||
// Input is const, function argument is not.
|
||||
(false, None, Some(_)) => {
|
||||
return Err(FunctionError::expected_non_const_input(
|
||||
name.clone(),
|
||||
name.to_string(),
|
||||
&function.span.clone().unwrap_or_default(),
|
||||
));
|
||||
}
|
||||
// When not found - Error out.
|
||||
(_, _, _) => {
|
||||
return Err(FunctionError::input_not_found(
|
||||
name.clone(),
|
||||
name.to_string(),
|
||||
&function.span.clone().unwrap_or_default(),
|
||||
));
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> CoreCircuit<'a, F, G> for Blake2s {
|
||||
mut arguments: Vec<ConstrainedValue<'a, F, G>>,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, ExpressionError> {
|
||||
assert_eq!(arguments.len(), 2); // asg enforced
|
||||
assert!(function.name.borrow().name == "hash"); // asg enforced
|
||||
assert!(function.name.borrow().name.as_ref() == "hash"); // asg enforced
|
||||
assert!(target.is_none()); // asg enforced
|
||||
let input = unwrap_argument(arguments.remove(1));
|
||||
let seed = unwrap_argument(arguments.remove(0));
|
||||
|
@ -19,11 +19,13 @@ use snarkvm_gadgets::traits::utilities::{
|
||||
int::{Int128, Int16, Int32, Int64, Int8},
|
||||
uint::{UInt128, UInt16, UInt32, UInt64, UInt8},
|
||||
};
|
||||
use std::fmt::Debug;
|
||||
use std::{convert::TryInto, fmt::Debug};
|
||||
|
||||
pub trait IntegerTrait: Sized + Clone + Debug {
|
||||
fn get_value(&self) -> Option<String>;
|
||||
|
||||
fn get_index(&self) -> Option<usize>;
|
||||
|
||||
fn get_bits(&self) -> Vec<Boolean>;
|
||||
}
|
||||
|
||||
@ -34,6 +36,10 @@ macro_rules! integer_trait_impl {
|
||||
self.value.map(|num| num.to_string())
|
||||
}
|
||||
|
||||
fn get_index(&self) -> Option<usize> {
|
||||
self.value.map(|num| num.try_into().ok()).flatten()
|
||||
}
|
||||
|
||||
fn get_bits(&self) -> Vec<Boolean> {
|
||||
self.bits.clone()
|
||||
}
|
||||
|
@ -4,15 +4,15 @@
|
||||
"imports": [],
|
||||
"circuits": {},
|
||||
"functions": {
|
||||
"{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\"}\"}": {
|
||||
"{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function main(a: [group; (2, 1)]) {\\\"}\"}": {
|
||||
"annotations": [],
|
||||
"identifier": "{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"identifier": "{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function main(a: [group; (2, 1)]) {\\\"}\"}",
|
||||
"input": [
|
||||
{
|
||||
"Variable": {
|
||||
"identifier": "{\"name\":\"a\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":15,\\\"col_stop\\\":16,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"identifier": "{\"name\":\"a\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":15,\\\"col_stop\\\":16,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function main(a: [group; (2, 1)]) {\\\"}\"}",
|
||||
"const_": false,
|
||||
"mutable": false,
|
||||
"mutable": true,
|
||||
"type_": {
|
||||
"Array": [
|
||||
{
|
||||
@ -37,7 +37,8 @@
|
||||
"line_stop": 1,
|
||||
"col_start": 15,
|
||||
"col_stop": 16,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": "function main(a: [group; (2, 1)]) {"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -52,14 +53,15 @@
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": false,
|
||||
"identifier": "{\"name\":\"b\",\"span\":\"{\\\"line_start\\\":2,\\\"line_stop\\\":2,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"b\",\"span\":\"{\\\"line_start\\\":2,\\\"line_stop\\\":2,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let b = [true; (6, 5, 4, 3, 2)];\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 2,
|
||||
"line_stop": 2,
|
||||
"col_start": 7,
|
||||
"col_stop": 8,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let b = [true; (6, 5, 4, 3, 2)];"
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -83,7 +85,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 12,
|
||||
"col_stop": 16,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let b = [true; (6, 5, 4, 3, 2)];"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -98,7 +101,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 11,
|
||||
"col_stop": 34,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let b = [true; (6, 5, 4, 3, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -112,7 +116,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 11,
|
||||
"col_stop": 34,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let b = [true; (6, 5, 4, 3, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -126,7 +131,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 11,
|
||||
"col_stop": 34,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let b = [true; (6, 5, 4, 3, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -140,7 +146,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 11,
|
||||
"col_stop": 34,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let b = [true; (6, 5, 4, 3, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -154,7 +161,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 11,
|
||||
"col_stop": 34,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let b = [true; (6, 5, 4, 3, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -163,7 +171,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 3,
|
||||
"col_stop": 34,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let b = [true; (6, 5, 4, 3, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -172,14 +181,15 @@
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": false,
|
||||
"identifier": "{\"name\":\"c\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"c\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let c: [u32; (1, 2)] = [0u32; (1, 2)];\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 3,
|
||||
"line_stop": 3,
|
||||
"col_start": 7,
|
||||
"col_stop": 8,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let c: [u32; (1, 2)] = [0u32; (1, 2)];"
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -218,7 +228,8 @@
|
||||
"line_stop": 3,
|
||||
"col_start": 27,
|
||||
"col_stop": 31,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let c: [u32; (1, 2)] = [0u32; (1, 2)];"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -233,7 +244,8 @@
|
||||
"line_stop": 3,
|
||||
"col_start": 26,
|
||||
"col_stop": 40,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let c: [u32; (1, 2)] = [0u32; (1, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -247,7 +259,8 @@
|
||||
"line_stop": 3,
|
||||
"col_start": 26,
|
||||
"col_stop": 40,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let c: [u32; (1, 2)] = [0u32; (1, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -256,7 +269,8 @@
|
||||
"line_stop": 3,
|
||||
"col_start": 3,
|
||||
"col_stop": 40,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let c: [u32; (1, 2)] = [0u32; (1, 2)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -265,14 +279,15 @@
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": false,
|
||||
"identifier": "{\"name\":\"d\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"d\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let d = [0i8; (1)];\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 4,
|
||||
"line_stop": 4,
|
||||
"col_start": 7,
|
||||
"col_stop": 8,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let d = [0i8; (1)];"
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -289,7 +304,8 @@
|
||||
"line_stop": 4,
|
||||
"col_start": 12,
|
||||
"col_stop": 15,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let d = [0i8; (1)];"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -304,7 +320,8 @@
|
||||
"line_stop": 4,
|
||||
"col_start": 11,
|
||||
"col_stop": 21,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let d = [0i8; (1)];"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -313,26 +330,29 @@
|
||||
"line_stop": 4,
|
||||
"col_start": 3,
|
||||
"col_stop": 21,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": " let d = [0i8; (1)];"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 1,
|
||||
"line_stop": 5,
|
||||
"line_stop": 7,
|
||||
"col_start": 35,
|
||||
"col_stop": 2,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": "function main(a: [group; (2, 1)]) {\n...\n}"
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 1,
|
||||
"line_stop": 5,
|
||||
"line_stop": 7,
|
||||
"col_start": 1,
|
||||
"col_stop": 2,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": "function main(a: [group; (2, 1)]) {\n...\n}\n\n\n\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,206 +1,218 @@
|
||||
{
|
||||
"name": "",
|
||||
"expected_input": [],
|
||||
"imports": [],
|
||||
"circuits": {
|
||||
"{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\"}\"}": {
|
||||
"circuit_name": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"members": [
|
||||
{
|
||||
"CircuitVariable": [
|
||||
"{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":2,\\\"line_stop\\\":2,\\\"col_start\\\":3,\\\"col_stop\\\":4,\\\"path\\\":\\\"\\\"}\"}",
|
||||
{
|
||||
"IntegerType": "U32"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"CircuitFunction": {
|
||||
"annotations": [],
|
||||
"identifier": "{\"name\":\"new\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":12,\\\"col_stop\\\":15,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"input": [],
|
||||
"output": {
|
||||
"Circuit": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\"}\"}"
|
||||
},
|
||||
"block": {
|
||||
"statements": [
|
||||
{
|
||||
"Definition": {
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": false,
|
||||
"identifier": "{\"name\":\"new\",\"span\":\"{\\\"line_start\\\":5,\\\"line_stop\\\":5,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 5,
|
||||
"line_stop": 5,
|
||||
"col_start": 9,
|
||||
"col_stop": 12,
|
||||
"path": ""
|
||||
}
|
||||
"name": "",
|
||||
"expected_input": [],
|
||||
"imports": [],
|
||||
"circuits": {
|
||||
"{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"circuit Foo {\\\"}\"}": {
|
||||
"circuit_name": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"circuit Foo {\\\"}\"}",
|
||||
"members": [
|
||||
{
|
||||
"CircuitVariable": [
|
||||
"{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":2,\\\"line_stop\\\":2,\\\"col_start\\\":3,\\\"col_stop\\\":4,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" x: u32\\\"}\"}",
|
||||
{
|
||||
"IntegerType": "U32"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"CircuitFunction": {
|
||||
"annotations": [],
|
||||
"identifier": "{\"name\":\"new\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":12,\\\"col_stop\\\":15,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" function new() -> Self {\\\"}\"}",
|
||||
"input": [],
|
||||
"output": {
|
||||
"Circuit": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"circuit Foo {\\\"}\"}"
|
||||
},
|
||||
"block": {
|
||||
"statements": [
|
||||
{
|
||||
"Definition": {
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"new\",\"span\":\"{\\\"line_start\\\":5,\\\"line_stop\\\":5,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let new: Self = Self {\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 5,
|
||||
"line_stop": 5,
|
||||
"col_start": 9,
|
||||
"col_stop": 12,
|
||||
"path": "",
|
||||
"content": " let new: Self = Self {"
|
||||
}
|
||||
],
|
||||
"type_": {
|
||||
"Circuit": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\"}\"}"
|
||||
},
|
||||
"value": {
|
||||
"CircuitInit": {
|
||||
"name": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"members": [
|
||||
{
|
||||
"identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":6,\\\"line_stop\\\":6,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"expression": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U32",
|
||||
"1",
|
||||
{
|
||||
"line_start": 6,
|
||||
"line_stop": 6,
|
||||
"col_start": 10,
|
||||
"col_stop": 14,
|
||||
"path": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"type_": {
|
||||
"Circuit": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"circuit Foo {\\\"}\"}"
|
||||
},
|
||||
"value": {
|
||||
"CircuitInit": {
|
||||
"name": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":9,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"circuit Foo {\\\"}\"}",
|
||||
"members": [
|
||||
{
|
||||
"identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":6,\\\"line_stop\\\":6,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" x: 1u32\\\"}\"}",
|
||||
"expression": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U32",
|
||||
"1",
|
||||
{
|
||||
"line_start": 6,
|
||||
"line_stop": 6,
|
||||
"col_start": 10,
|
||||
"col_stop": 14,
|
||||
"path": "",
|
||||
"content": " x: 1u32"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 5,
|
||||
"line_stop": 7,
|
||||
"col_start": 21,
|
||||
"col_stop": 6,
|
||||
"path": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 5,
|
||||
"line_stop": 7,
|
||||
"col_start": 5,
|
||||
"col_stop": 6,
|
||||
"path": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Return": {
|
||||
"expression": {
|
||||
"Identifier": "{\"name\":\"new\",\"span\":\"{\\\"line_start\\\":9,\\\"line_stop\\\":9,\\\"col_start\\\":12,\\\"col_stop\\\":15,\\\"path\\\":\\\"\\\"}\"}"
|
||||
},
|
||||
"span": {
|
||||
"line_start": 9,
|
||||
"line_stop": 9,
|
||||
"col_start": 5,
|
||||
"col_stop": 15,
|
||||
"path": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 4,
|
||||
"line_stop": 10,
|
||||
"col_start": 26,
|
||||
"col_stop": 4,
|
||||
"path": ""
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 4,
|
||||
"line_stop": 10,
|
||||
"col_start": 3,
|
||||
"col_stop": 4,
|
||||
"path": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"functions": {
|
||||
"{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":13,\\\"line_stop\\\":13,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\"}\"}": {
|
||||
"annotations": [],
|
||||
"identifier": "{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":13,\\\"line_stop\\\":13,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"input": [],
|
||||
"output": {
|
||||
"Tuple": []
|
||||
},
|
||||
"block": {
|
||||
"statements": [
|
||||
{
|
||||
"Definition": {
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": false,
|
||||
"identifier": "{\"name\":\"foo\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":7,\\\"col_stop\\\":10,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 7,
|
||||
"col_stop": 10,
|
||||
"path": ""
|
||||
}
|
||||
}
|
||||
],
|
||||
"type_": {
|
||||
"Circuit": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":12,\\\"col_stop\\\":15,\\\"path\\\":\\\"\\\"}\"}"
|
||||
},
|
||||
"value": {
|
||||
"Call": {
|
||||
"function": {
|
||||
"CircuitStaticFunctionAccess": {
|
||||
"circuit": {
|
||||
"Identifier": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":18,\\\"col_stop\\\":21,\\\"path\\\":\\\"\\\"}\"}"
|
||||
},
|
||||
"name": "{\"name\":\"new\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":23,\\\"col_stop\\\":26,\\\"path\\\":\\\"\\\"}\"}",
|
||||
],
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 18,
|
||||
"col_stop": 26,
|
||||
"path": ""
|
||||
"line_start": 5,
|
||||
"line_stop": 7,
|
||||
"col_start": 21,
|
||||
"col_stop": 6,
|
||||
"path": "",
|
||||
"content": " let new: Self = Self {\n...\n };"
|
||||
}
|
||||
}
|
||||
},
|
||||
"arguments": [],
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 18,
|
||||
"col_stop": 28,
|
||||
"path": ""
|
||||
"line_start": 5,
|
||||
"line_stop": 7,
|
||||
"col_start": 5,
|
||||
"col_stop": 6,
|
||||
"path": "",
|
||||
"content": " let new: Self = Self {\n...\n };"
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 3,
|
||||
"col_stop": 28,
|
||||
"path": ""
|
||||
{
|
||||
"Return": {
|
||||
"expression": {
|
||||
"Identifier": "{\"name\":\"new\",\"span\":\"{\\\"line_start\\\":9,\\\"line_stop\\\":9,\\\"col_start\\\":12,\\\"col_stop\\\":15,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" return new\\\"}\"}"
|
||||
},
|
||||
"span": {
|
||||
"line_start": 9,
|
||||
"line_stop": 9,
|
||||
"col_start": 5,
|
||||
"col_stop": 15,
|
||||
"path": "",
|
||||
"content": " return new"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 4,
|
||||
"line_stop": 10,
|
||||
"col_start": 26,
|
||||
"col_stop": 4,
|
||||
"path": "",
|
||||
"content": " function new() -> Self {\n...\n }"
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 4,
|
||||
"line_stop": 10,
|
||||
"col_start": 3,
|
||||
"col_stop": 4,
|
||||
"path": "",
|
||||
"content": " function new() -> Self {\n...\n }\n\n\n\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"functions": {
|
||||
"{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":13,\\\"line_stop\\\":13,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function main() {\\\"}\"}": {
|
||||
"annotations": [],
|
||||
"identifier": "{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":13,\\\"line_stop\\\":13,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function main() {\\\"}\"}",
|
||||
"input": [],
|
||||
"output": {
|
||||
"Tuple": []
|
||||
},
|
||||
"block": {
|
||||
"statements": [
|
||||
{
|
||||
"Definition": {
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"foo\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":7,\\\"col_stop\\\":10,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let foo: Foo = Foo::new();\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 7,
|
||||
"col_stop": 10,
|
||||
"path": "",
|
||||
"content": " let foo: Foo = Foo::new();"
|
||||
}
|
||||
}
|
||||
],
|
||||
"type_": {
|
||||
"Circuit": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":12,\\\"col_stop\\\":15,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let foo: Foo = Foo::new();\\\"}\"}"
|
||||
},
|
||||
"value": {
|
||||
"Call": {
|
||||
"function": {
|
||||
"CircuitStaticFunctionAccess": {
|
||||
"circuit": {
|
||||
"Identifier": "{\"name\":\"Foo\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":18,\\\"col_stop\\\":21,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let foo: Foo = Foo::new();\\\"}\"}"
|
||||
},
|
||||
"name": "{\"name\":\"new\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":23,\\\"col_stop\\\":26,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let foo: Foo = Foo::new();\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 18,
|
||||
"col_stop": 26,
|
||||
"path": "",
|
||||
"content": " let foo: Foo = Foo::new();"
|
||||
}
|
||||
}
|
||||
},
|
||||
"arguments": [],
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 18,
|
||||
"col_stop": 28,
|
||||
"path": "",
|
||||
"content": " let foo: Foo = Foo::new();"
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 14,
|
||||
"line_stop": 14,
|
||||
"col_start": 3,
|
||||
"col_stop": 28,
|
||||
"path": "",
|
||||
"content": " let foo: Foo = Foo::new();"
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 13,
|
||||
"line_stop": 15,
|
||||
"col_start": 17,
|
||||
"col_stop": 2,
|
||||
"path": ""
|
||||
}
|
||||
},
|
||||
],
|
||||
"span": {
|
||||
"line_start": 13,
|
||||
"line_stop": 15,
|
||||
"col_start": 1,
|
||||
"col_start": 17,
|
||||
"col_stop": 2,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": "function main() {\n...\n}"
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 13,
|
||||
"line_stop": 15,
|
||||
"col_start": 1,
|
||||
"col_stop": 2,
|
||||
"path": "",
|
||||
"content": "function main() {\n...\n}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,128 +1,136 @@
|
||||
{
|
||||
"name": "",
|
||||
"expected_input": [],
|
||||
"imports": [],
|
||||
"circuits": {},
|
||||
"functions": {
|
||||
"{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\"}\"}": {
|
||||
"annotations": [],
|
||||
"identifier": "{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"input": [],
|
||||
"output": {
|
||||
"Tuple": []
|
||||
},
|
||||
"block": {
|
||||
"statements": [
|
||||
{
|
||||
"Definition": {
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":2,\\\"line_stop\\\":2,\\\"col_start\\\":11,\\\"col_stop\\\":12,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"span": {
|
||||
"name": "",
|
||||
"expected_input": [],
|
||||
"imports": [],
|
||||
"circuits": {},
|
||||
"functions": {
|
||||
"{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function main() {\\\"}\"}": {
|
||||
"annotations": [],
|
||||
"identifier": "{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function main() {\\\"}\"}",
|
||||
"input": [],
|
||||
"output": {
|
||||
"Tuple": []
|
||||
},
|
||||
"block": {
|
||||
"statements": [
|
||||
{
|
||||
"Definition": {
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":2,\\\"line_stop\\\":2,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let x = 10u32;\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 2,
|
||||
"line_stop": 2,
|
||||
"col_start": 7,
|
||||
"col_stop": 8,
|
||||
"path": "",
|
||||
"content": " let x = 10u32;"
|
||||
}
|
||||
}
|
||||
],
|
||||
"type_": null,
|
||||
"value": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U32",
|
||||
"10",
|
||||
{
|
||||
"line_start": 2,
|
||||
"line_stop": 2,
|
||||
"col_start": 7,
|
||||
"col_stop": 12,
|
||||
"path": ""
|
||||
"col_start": 11,
|
||||
"col_stop": 16,
|
||||
"path": "",
|
||||
"content": " let x = 10u32;"
|
||||
}
|
||||
}
|
||||
],
|
||||
"type_": null,
|
||||
"value": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U32",
|
||||
"10",
|
||||
{
|
||||
"line_start": 2,
|
||||
"line_stop": 2,
|
||||
"col_start": 15,
|
||||
"col_stop": 20,
|
||||
"path": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 2,
|
||||
"line_stop": 2,
|
||||
"col_start": 3,
|
||||
"col_stop": 20,
|
||||
"path": ""
|
||||
]
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 2,
|
||||
"line_stop": 2,
|
||||
"col_start": 3,
|
||||
"col_stop": 16,
|
||||
"path": "",
|
||||
"content": " let x = 10u32;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Assign": {
|
||||
"operation": "Assign",
|
||||
"assignee": {
|
||||
"identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":3,\\\"col_stop\\\":4,\\\"path\\\":\\\"\\\"}\"}",
|
||||
"accesses": [],
|
||||
"span": {
|
||||
"line_start": 3,
|
||||
"line_stop": 3,
|
||||
"col_start": 3,
|
||||
"col_stop": 4,
|
||||
"path": ""
|
||||
}
|
||||
},
|
||||
"value": {
|
||||
"Binary": {
|
||||
"left": {
|
||||
"Identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":3,\\\"col_stop\\\":4,\\\"path\\\":\\\"\\\"}\"}"
|
||||
},
|
||||
"right": {
|
||||
"Value": {
|
||||
"Implicit": [
|
||||
"20",
|
||||
{
|
||||
"line_start": 3,
|
||||
"line_stop": 3,
|
||||
"col_start": 8,
|
||||
"col_stop": 10,
|
||||
"path": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"op": "Add",
|
||||
"span": {
|
||||
"line_start": 3,
|
||||
"line_stop": 3,
|
||||
"col_start": 3,
|
||||
"col_stop": 10,
|
||||
"path": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
"Assign": {
|
||||
"operation": "Assign",
|
||||
"assignee": {
|
||||
"identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":3,\\\"col_stop\\\":4,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" x += 20;\\\"}\"}",
|
||||
"accesses": [],
|
||||
"span": {
|
||||
"line_start": 3,
|
||||
"line_stop": 3,
|
||||
"col_start": 3,
|
||||
"col_stop": 10,
|
||||
"path": ""
|
||||
"col_stop": 4,
|
||||
"path": "",
|
||||
"content": " x += 20;"
|
||||
}
|
||||
},
|
||||
"value": {
|
||||
"Binary": {
|
||||
"left": {
|
||||
"Identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":3,\\\"col_stop\\\":4,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" x += 20;\\\"}\"}"
|
||||
},
|
||||
"right": {
|
||||
"Value": {
|
||||
"Implicit": [
|
||||
"20",
|
||||
{
|
||||
"line_start": 3,
|
||||
"line_stop": 3,
|
||||
"col_start": 8,
|
||||
"col_stop": 10,
|
||||
"path": "",
|
||||
"content": " x += 20;"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"op": "Add",
|
||||
"span": {
|
||||
"line_start": 3,
|
||||
"line_stop": 3,
|
||||
"col_start": 3,
|
||||
"col_stop": 10,
|
||||
"path": "",
|
||||
"content": " x += 20;"
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 3,
|
||||
"line_stop": 3,
|
||||
"col_start": 3,
|
||||
"col_stop": 10,
|
||||
"path": "",
|
||||
"content": " x += 20;"
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 1,
|
||||
"line_stop": 4,
|
||||
"col_start": 17,
|
||||
"col_stop": 2,
|
||||
"path": ""
|
||||
}
|
||||
},
|
||||
],
|
||||
"span": {
|
||||
"line_start": 1,
|
||||
"line_stop": 4,
|
||||
"col_start": 1,
|
||||
"col_start": 17,
|
||||
"col_stop": 2,
|
||||
"path": ""
|
||||
"path": "",
|
||||
"content": "function main() {\n...\n}"
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 1,
|
||||
"line_stop": 4,
|
||||
"col_start": 1,
|
||||
"col_stop": 2,
|
||||
"path": "",
|
||||
"content": "function main() {\n...\n}\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -33,25 +33,7 @@ pub enum ImportParserError {
|
||||
AsgConvertError(#[from] AsgConvertError),
|
||||
}
|
||||
|
||||
impl LeoError for ImportParserError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
ImportParserError::Error(error) => error.get_path(),
|
||||
ImportParserError::SyntaxError(error) => error.get_path(),
|
||||
ImportParserError::AsgConvertError(error) => error.get_path(),
|
||||
ImportParserError::DeprecatedError(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
ImportParserError::Error(error) => error.set_path(path, contents),
|
||||
ImportParserError::SyntaxError(error) => error.set_path(path, contents),
|
||||
ImportParserError::AsgConvertError(error) => error.set_path(path, contents),
|
||||
ImportParserError::DeprecatedError(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for ImportParserError {}
|
||||
|
||||
impl Into<AsgConvertError> for ImportParserError {
|
||||
fn into(self) -> AsgConvertError {
|
||||
|
@ -48,6 +48,9 @@ version = "0.3"
|
||||
[dependencies.indexmap]
|
||||
version = "1.6"
|
||||
|
||||
[dependencies.tendril]
|
||||
version = "0.4"
|
||||
|
||||
[features]
|
||||
default = [ ]
|
||||
ci_skip = [ ]
|
||||
|
@ -28,19 +28,7 @@ impl DeprecatedError {
|
||||
}
|
||||
}
|
||||
|
||||
impl LeoError for DeprecatedError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
DeprecatedError::Error(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
DeprecatedError::Error(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for DeprecatedError {}
|
||||
|
||||
impl DeprecatedError {
|
||||
pub fn mut_function_input(mut span: Span) -> Self {
|
||||
|
@ -30,23 +30,7 @@ pub enum SyntaxError {
|
||||
DeprecatedError(#[from] DeprecatedError),
|
||||
}
|
||||
|
||||
impl LeoError for SyntaxError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
SyntaxError::Error(error) => error.get_path(),
|
||||
SyntaxError::TokenError(error) => error.get_path(),
|
||||
SyntaxError::DeprecatedError(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
SyntaxError::Error(error) => error.set_path(path, contents),
|
||||
SyntaxError::TokenError(error) => error.set_path(path, contents),
|
||||
SyntaxError::DeprecatedError(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for SyntaxError {}
|
||||
|
||||
impl SyntaxError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
@ -105,4 +89,8 @@ impl SyntaxError {
|
||||
span,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn illegal_self_const(span: &Span) -> Self {
|
||||
Self::new_from_span("cannot have const self".to_string(), span)
|
||||
}
|
||||
}
|
||||
|
@ -22,19 +22,7 @@ pub enum TokenError {
|
||||
Error(#[from] FormattedError),
|
||||
}
|
||||
|
||||
impl LeoError for TokenError {
|
||||
fn get_path(&self) -> Option<&str> {
|
||||
match self {
|
||||
TokenError::Error(error) => error.get_path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_path(&mut self, path: &str, contents: &[String]) {
|
||||
match self {
|
||||
TokenError::Error(error) => error.set_path(path, contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LeoError for TokenError {}
|
||||
|
||||
impl TokenError {
|
||||
fn new_from_span(message: String, span: &Span) -> Self {
|
||||
|
@ -18,6 +18,7 @@ use std::unimplemented;
|
||||
|
||||
use crate::{tokenizer::*, SyntaxError, SyntaxResult, Token, KEYWORD_TOKENS};
|
||||
use leo_ast::*;
|
||||
use tendril::format_tendril;
|
||||
|
||||
/// Stores a program in tokenized format plus additional context.
|
||||
/// May be converted into a [`Program`] AST by parsing all tokens.
|
||||
@ -149,11 +150,11 @@ impl ParserContext {
|
||||
span,
|
||||
}) => {
|
||||
*i -= 1;
|
||||
GroupCoordinate::Number(format!("-{}", value), span.clone())
|
||||
GroupCoordinate::Number(format_tendril!("-{}", value), span.clone())
|
||||
}
|
||||
_ => GroupCoordinate::SignLow,
|
||||
},
|
||||
Token::Ident(x) if x == "_" => GroupCoordinate::Inferred,
|
||||
Token::Ident(x) if x.as_ref() == "_" => GroupCoordinate::Inferred,
|
||||
Token::Int(value) => GroupCoordinate::Number(value.clone(), token.span.clone()),
|
||||
_ => return None,
|
||||
})
|
||||
@ -280,7 +281,7 @@ impl ParserContext {
|
||||
pub fn expect_loose_identifier(&mut self) -> SyntaxResult<Identifier> {
|
||||
if let Some(token) = self.eat_any(KEYWORD_TOKENS) {
|
||||
return Ok(Identifier {
|
||||
name: token.token.to_string(),
|
||||
name: token.token.to_string().into(),
|
||||
span: token.span,
|
||||
});
|
||||
}
|
||||
|
@ -14,6 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use tendril::format_tendril;
|
||||
|
||||
use super::*;
|
||||
|
||||
const INT_TYPES: &[Token] = &[
|
||||
@ -368,10 +370,17 @@ impl ParserContext {
|
||||
// hack for const signed integer overflow issues
|
||||
if matches!(operation, UnaryOperation::Negate) {
|
||||
if let Expression::Value(ValueExpression::Integer(type_, value, span)) = inner {
|
||||
inner = Expression::Value(ValueExpression::Integer(type_, format!("-{}", value), &op.span + &span));
|
||||
inner = Expression::Value(ValueExpression::Integer(
|
||||
type_,
|
||||
format_tendril!("-{}", value),
|
||||
&op.span + &span,
|
||||
));
|
||||
continue;
|
||||
} else if let Expression::Value(ValueExpression::Implicit(value, span)) = inner {
|
||||
inner = Expression::Value(ValueExpression::Implicit(format!("-{}", value), &op.span + &span));
|
||||
inner = Expression::Value(ValueExpression::Implicit(
|
||||
format_tendril!("-{}", value),
|
||||
&op.span + &span,
|
||||
));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -574,8 +583,8 @@ impl ParserContext {
|
||||
None => Expression::Value(ValueExpression::Implicit(value, span)),
|
||||
}
|
||||
}
|
||||
Token::True => Expression::Value(ValueExpression::Boolean("true".to_string(), span)),
|
||||
Token::False => Expression::Value(ValueExpression::Boolean("false".to_string(), span)),
|
||||
Token::True => Expression::Value(ValueExpression::Boolean("true".into(), span)),
|
||||
Token::False => Expression::Value(ValueExpression::Boolean("false".into(), span)),
|
||||
Token::AddressLit(value) => Expression::Value(ValueExpression::Address(value, span)),
|
||||
Token::Address => {
|
||||
self.expect(Token::LeftParen)?;
|
||||
@ -683,7 +692,7 @@ impl ParserContext {
|
||||
}
|
||||
Token::BigSelf => {
|
||||
let ident = Identifier {
|
||||
name: token.to_string(),
|
||||
name: token.to_string().into(),
|
||||
span,
|
||||
};
|
||||
if !self.fuzzy_struct_state && self.peek()?.token == Token::LeftCurly {
|
||||
@ -694,7 +703,7 @@ impl ParserContext {
|
||||
}
|
||||
Token::Input | Token::LittleSelf => {
|
||||
let ident = Identifier {
|
||||
name: token.to_string(),
|
||||
name: token.to_string().into(),
|
||||
span,
|
||||
};
|
||||
Expression::Identifier(ident)
|
||||
|
@ -14,6 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use tendril::format_tendril;
|
||||
|
||||
use crate::KEYWORD_TOKENS;
|
||||
|
||||
use super::*;
|
||||
@ -42,7 +44,7 @@ impl ParserContext {
|
||||
let (id, function) = self.parse_function()?;
|
||||
functions.insert(id, function);
|
||||
}
|
||||
Token::Ident(ident) if ident == "test" => {
|
||||
Token::Ident(ident) if ident.as_ref() == "test" => {
|
||||
return Err(SyntaxError::DeprecatedError(DeprecatedError::test_function(
|
||||
&token.span,
|
||||
)));
|
||||
@ -60,7 +62,7 @@ impl ParserContext {
|
||||
Token::Import,
|
||||
Token::Circuit,
|
||||
Token::Function,
|
||||
Token::Ident("test".to_string()),
|
||||
Token::Ident("test".into()),
|
||||
Token::At,
|
||||
],
|
||||
&token.span,
|
||||
@ -83,7 +85,7 @@ impl ParserContext {
|
||||
pub fn parse_annotation(&mut self) -> SyntaxResult<Annotation> {
|
||||
let start = self.expect(Token::At)?;
|
||||
let name = self.expect_ident()?;
|
||||
if name.name == "context" {
|
||||
if name.name.as_ref() == "context" {
|
||||
return Err(SyntaxError::DeprecatedError(DeprecatedError::context_annotation(
|
||||
&name.span,
|
||||
)));
|
||||
@ -186,25 +188,24 @@ impl ParserContext {
|
||||
match &self.peek()?.token {
|
||||
Token::Minus => {
|
||||
let span = self.expect(Token::Minus)?;
|
||||
base.name += "-";
|
||||
base.span = base.span + span;
|
||||
let next = self.expect_loose_identifier()?;
|
||||
base.name += &next.name;
|
||||
base.name = format_tendril!("{}-{}", base.name, next.name);
|
||||
base.span = base.span + next.span;
|
||||
}
|
||||
Token::Int(_) => {
|
||||
let (num, span) = self.eat_int().unwrap();
|
||||
base.name += &num.value;
|
||||
base.name = format_tendril!("{}{}", base.name, num.value);
|
||||
base.span = base.span + span;
|
||||
}
|
||||
Token::Ident(_) => {
|
||||
let next = self.expect_ident()?;
|
||||
base.name += &next.name;
|
||||
base.name = format_tendril!("{}{}", base.name, next.name);
|
||||
base.span = base.span + next.span;
|
||||
}
|
||||
x if KEYWORD_TOKENS.contains(&x) => {
|
||||
let next = self.expect_loose_identifier()?;
|
||||
base.name += &next.name;
|
||||
base.name = format_tendril!("{}{}", base.name, next.name);
|
||||
base.span = base.span + next.span;
|
||||
}
|
||||
_ => break,
|
||||
@ -212,7 +213,7 @@ impl ParserContext {
|
||||
}
|
||||
|
||||
// Return an error if the package name contains a keyword.
|
||||
if let Some(token) = KEYWORD_TOKENS.iter().find(|x| x.to_string() == base.name) {
|
||||
if let Some(token) = KEYWORD_TOKENS.iter().find(|x| x.to_string() == base.name.as_ref()) {
|
||||
return Err(SyntaxError::unexpected_str(token, "package name", &base.span));
|
||||
}
|
||||
|
||||
@ -311,7 +312,7 @@ impl ParserContext {
|
||||
if let Some(token) = self.eat(Token::Input) {
|
||||
return Ok(FunctionInput::InputKeyword(InputKeyword {
|
||||
identifier: Identifier {
|
||||
name: token.token.to_string(),
|
||||
name: token.token.to_string().into(),
|
||||
span: token.span,
|
||||
},
|
||||
}));
|
||||
@ -320,22 +321,25 @@ impl ParserContext {
|
||||
let mutable = self.eat(Token::Mut);
|
||||
let mut name = if let Some(token) = self.eat(Token::LittleSelf) {
|
||||
Identifier {
|
||||
name: token.token.to_string(),
|
||||
name: token.token.to_string().into(),
|
||||
span: token.span,
|
||||
}
|
||||
} else {
|
||||
self.expect_ident()?
|
||||
};
|
||||
if name.name == "self" {
|
||||
if name.name.as_ref() == "self" {
|
||||
if let Some(mutable) = &mutable {
|
||||
// Handle `mut self`.
|
||||
name.span = &mutable.span + &name.span;
|
||||
name.name = "mut self".to_string();
|
||||
name.name = "mut self".to_string().into();
|
||||
return Ok(FunctionInput::MutSelfKeyword(MutSelfKeyword { identifier: name }));
|
||||
} else if let Some(const_) = &const_ {
|
||||
// Handle `const self`.
|
||||
name.span = &const_.span + &name.span;
|
||||
name.name = "const self".to_string();
|
||||
name.name = "const self".to_string().into();
|
||||
return Ok(FunctionInput::ConstSelfKeyword(ConstSelfKeyword { identifier: name }));
|
||||
}
|
||||
// Handle `self`.
|
||||
return Ok(FunctionInput::SelfKeyword(SelfKeyword { identifier: name }));
|
||||
}
|
||||
|
||||
|
@ -37,16 +37,7 @@ pub type SyntaxResult<T> = Result<T, SyntaxError>;
|
||||
|
||||
/// Creates a new program from a given file path and source code text.
|
||||
pub fn parse(path: &str, source: &str) -> SyntaxResult<Program> {
|
||||
let mut tokens = ParserContext::new(crate::tokenize(path, source)?);
|
||||
let mut tokens = ParserContext::new(crate::tokenize(path, source.into())?);
|
||||
|
||||
match tokens.parse_program() {
|
||||
Ok(x) => Ok(x),
|
||||
Err(mut e) => {
|
||||
e.set_path(
|
||||
path,
|
||||
&source.lines().map(|x| x.to_string()).collect::<Vec<String>>()[..],
|
||||
);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
tokens.parse_program()
|
||||
}
|
||||
|
@ -17,32 +17,34 @@
|
||||
use crate::tokenizer::{FormattedStringPart, Token};
|
||||
use leo_ast::Span;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tendril::StrTendril;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
///
|
||||
/// Returns a reference to bytes from the given input if the given string is equal to the bytes,
|
||||
/// otherwise returns [`None`].
|
||||
/// Returns the length of the given `wanted` string if the string can be eaten, otherwise returns [`None`].
|
||||
/// A string can be eaten if its bytes are at the front of the given `input` array.
|
||||
///
|
||||
fn eat<'a>(input: &'a [u8], wanted: &str) -> Option<&'a [u8]> {
|
||||
fn eat(input: &[u8], wanted: &str) -> Option<usize> {
|
||||
let wanted = wanted.as_bytes();
|
||||
if input.len() < wanted.len() {
|
||||
return None;
|
||||
}
|
||||
if &input[0..wanted.len()] == wanted {
|
||||
return Some(&input[wanted.len()..]);
|
||||
return Some(wanted.len());
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a reference to the bytes of an identifier and the remaining bytes from the given input.
|
||||
/// Returns [`None`] if the bytes do not represent an identifier.
|
||||
/// Returns a new `StrTendril` string if an identifier can be eaten, otherwise returns [`None`].
|
||||
/// An identifier can be eaten if its bytes are at the front of the given `input_tendril` string.
|
||||
///
|
||||
fn eat_identifier(input: &[u8]) -> Option<(&[u8], &[u8])> {
|
||||
if input.is_empty() {
|
||||
fn eat_identifier(input_tendril: &StrTendril) -> Option<StrTendril> {
|
||||
if input_tendril.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let input = input_tendril[..].as_bytes();
|
||||
if !input[0].is_ascii_alphabetic() && input[0] != b'_' {
|
||||
return None;
|
||||
}
|
||||
@ -53,20 +55,21 @@ fn eat_identifier(input: &[u8]) -> Option<(&[u8], &[u8])> {
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
Some((&input[0..i], &input[i..]))
|
||||
Some(input_tendril.subtendril(0, i as u32))
|
||||
}
|
||||
|
||||
impl Token {
|
||||
///
|
||||
/// Returns a reference to the remaining bytes and the bytes of a number from the given input.
|
||||
/// Returns [`None`] if the bytes do not represent a number.
|
||||
/// Returns a tuple: [(integer length, integer token)] if an integer can be eaten, otherwise returns [`None`].
|
||||
/// An integer can be eaten if its bytes are at the front of the given `input_tendril` string.
|
||||
///
|
||||
fn gobble_int(input: &[u8]) -> (&[u8], Option<Token>) {
|
||||
if input.is_empty() {
|
||||
return (input, None);
|
||||
fn eat_integer(input_tendril: &StrTendril) -> (usize, Option<Token>) {
|
||||
if input_tendril.is_empty() {
|
||||
return (0, None);
|
||||
}
|
||||
let input = input_tendril[..].as_bytes();
|
||||
if !input[0].is_ascii_digit() {
|
||||
return (input, None);
|
||||
return (0, None);
|
||||
}
|
||||
let mut i = 1;
|
||||
let mut is_hex = false;
|
||||
@ -86,22 +89,20 @@ impl Token {
|
||||
|
||||
i += 1;
|
||||
}
|
||||
(
|
||||
&input[i..],
|
||||
Some(Token::Int(String::from_utf8(input[0..i].to_vec()).unwrap_or_default())),
|
||||
)
|
||||
(i, Some(Token::Int(input_tendril.subtendril(0, i as u32))))
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a reference to the remaining bytes and the bytes of a [`Token`] from the given input.
|
||||
/// Returns [`None`] if the bytes do not represent a token.
|
||||
/// Returns a tuple: [(token length, token)] if the next token can be eaten, otherwise returns [`None`].
|
||||
/// The next token can be eaten if the bytes at the front of the given `input_tendril` string can be scanned into a token.
|
||||
///
|
||||
pub(crate) fn gobble(input: &[u8]) -> (&[u8], Option<Token>) {
|
||||
if input.is_empty() {
|
||||
return (input, None);
|
||||
pub(crate) fn eat(input_tendril: StrTendril) -> (usize, Option<Token>) {
|
||||
if input_tendril.is_empty() {
|
||||
return (0, None);
|
||||
}
|
||||
let input = input_tendril[..].as_bytes();
|
||||
match input[0] {
|
||||
x if x.is_ascii_whitespace() => return (&input[1..], None),
|
||||
x if x.is_ascii_whitespace() => return (1, None),
|
||||
b'"' => {
|
||||
let mut i = 1;
|
||||
let mut in_escape = false;
|
||||
@ -124,7 +125,7 @@ impl Token {
|
||||
}
|
||||
if start < i {
|
||||
segments.push(FormattedStringPart::Const(
|
||||
String::from_utf8_lossy(&input[start..i]).to_string(),
|
||||
input_tendril.subtendril(start as u32, (i - start) as u32),
|
||||
));
|
||||
}
|
||||
segments.push(FormattedStringPart::Container);
|
||||
@ -138,186 +139,171 @@ impl Token {
|
||||
i += 1;
|
||||
}
|
||||
if i == input.len() {
|
||||
return (input, None);
|
||||
return (0, None);
|
||||
}
|
||||
if start < i {
|
||||
segments.push(FormattedStringPart::Const(
|
||||
String::from_utf8_lossy(&input[start..i]).to_string(),
|
||||
input_tendril.subtendril(start as u32, (i - start) as u32),
|
||||
));
|
||||
}
|
||||
return (&input[(i + 1)..], Some(Token::FormattedString(segments)));
|
||||
return (i + 1, Some(Token::FormattedString(segments)));
|
||||
}
|
||||
x if x.is_ascii_digit() => {
|
||||
return Self::gobble_int(input);
|
||||
return Self::eat_integer(&input_tendril);
|
||||
}
|
||||
b'!' => {
|
||||
if let Some(input) = eat(input, "!=") {
|
||||
return (input, Some(Token::NotEq));
|
||||
if let Some(len) = eat(input, "!=") {
|
||||
return (len, Some(Token::NotEq));
|
||||
}
|
||||
return (&input[1..], Some(Token::Not));
|
||||
return (1, Some(Token::Not));
|
||||
}
|
||||
b'?' => {
|
||||
return (&input[1..], Some(Token::Question));
|
||||
return (1, Some(Token::Question));
|
||||
}
|
||||
b'&' => {
|
||||
if let Some(input) = eat(input, "&&") {
|
||||
if let Some(input) = eat(input, "=") {
|
||||
return (input, Some(Token::AndEq));
|
||||
if let Some(len) = eat(input, "&&") {
|
||||
if let Some(inner_len) = eat(&input[len..], "=") {
|
||||
return (len + inner_len, Some(Token::AndEq));
|
||||
}
|
||||
return (input, Some(Token::And));
|
||||
} else if let Some(input) = eat(input, "&=") {
|
||||
return (input, Some(Token::BitAndEq));
|
||||
return (len, Some(Token::And));
|
||||
} else if let Some(len) = eat(input, "&=") {
|
||||
return (len, Some(Token::BitAndEq));
|
||||
}
|
||||
return (&input[1..], Some(Token::BitAnd));
|
||||
return (1, Some(Token::BitAnd));
|
||||
}
|
||||
b'(' => return (&input[1..], Some(Token::LeftParen)),
|
||||
b')' => return (&input[1..], Some(Token::RightParen)),
|
||||
b'(' => return (1, Some(Token::LeftParen)),
|
||||
b')' => return (1, Some(Token::RightParen)),
|
||||
b'*' => {
|
||||
if let Some(input) = eat(input, "**") {
|
||||
if let Some(input) = eat(input, "=") {
|
||||
return (input, Some(Token::ExpEq));
|
||||
if let Some(len) = eat(input, "**") {
|
||||
if let Some(inner_len) = eat(&input[len..], "=") {
|
||||
return (len + inner_len, Some(Token::ExpEq));
|
||||
}
|
||||
return (input, Some(Token::Exp));
|
||||
} else if let Some(input) = eat(input, "*=") {
|
||||
return (input, Some(Token::MulEq));
|
||||
return (len, Some(Token::Exp));
|
||||
} else if let Some(len) = eat(input, "*=") {
|
||||
return (len, Some(Token::MulEq));
|
||||
}
|
||||
return (&input[1..], Some(Token::Mul));
|
||||
return (1, Some(Token::Mul));
|
||||
}
|
||||
b'+' => {
|
||||
if let Some(input) = eat(input, "+=") {
|
||||
return (input, Some(Token::AddEq));
|
||||
if let Some(len) = eat(input, "+=") {
|
||||
return (len, Some(Token::AddEq));
|
||||
}
|
||||
return (&input[1..], Some(Token::Add));
|
||||
return (1, Some(Token::Add));
|
||||
}
|
||||
b',' => return (&input[1..], Some(Token::Comma)),
|
||||
b',' => return (1, Some(Token::Comma)),
|
||||
b'-' => {
|
||||
if let Some(input) = eat(input, "->") {
|
||||
return (input, Some(Token::Arrow));
|
||||
} else if let Some(input) = eat(input, "-=") {
|
||||
return (input, Some(Token::MinusEq));
|
||||
if let Some(len) = eat(input, "->") {
|
||||
return (len, Some(Token::Arrow));
|
||||
} else if let Some(len) = eat(input, "-=") {
|
||||
return (len, Some(Token::MinusEq));
|
||||
}
|
||||
return (&input[1..], Some(Token::Minus));
|
||||
return (1, Some(Token::Minus));
|
||||
}
|
||||
b'.' => {
|
||||
if let Some(input) = eat(input, "...") {
|
||||
return (input, Some(Token::DotDotDot));
|
||||
} else if let Some(input) = eat(input, "..") {
|
||||
return (input, Some(Token::DotDot));
|
||||
if let Some(len) = eat(input, "...") {
|
||||
return (len, Some(Token::DotDotDot));
|
||||
} else if let Some(len) = eat(input, "..") {
|
||||
return (len, Some(Token::DotDot));
|
||||
}
|
||||
return (&input[1..], Some(Token::Dot));
|
||||
return (1, Some(Token::Dot));
|
||||
}
|
||||
b'/' => {
|
||||
if eat(input, "//").is_some() {
|
||||
let eol = input.iter().position(|x| *x == b'\n');
|
||||
let (input, comment) = if let Some(eol) = eol {
|
||||
(&input[(eol + 1)..], &input[..eol])
|
||||
} else {
|
||||
(&input[input.len()..input.len()], input)
|
||||
};
|
||||
return (
|
||||
input,
|
||||
Some(Token::CommentLine(String::from_utf8_lossy(comment).to_string())),
|
||||
);
|
||||
let len = if let Some(eol) = eol { eol + 1 } else { input.len() };
|
||||
return (len, Some(Token::CommentLine(input_tendril.subtendril(0, len as u32))));
|
||||
} else if eat(input, "/*").is_some() {
|
||||
if input.is_empty() {
|
||||
return (input, None);
|
||||
return (0, None);
|
||||
}
|
||||
let eol = input.windows(2).skip(2).position(|x| x[0] == b'*' && x[1] == b'/');
|
||||
let (input, comment) = if let Some(eol) = eol {
|
||||
(&input[(eol + 4)..], &input[..eol + 4])
|
||||
} else {
|
||||
(&input[input.len()..input.len()], input)
|
||||
};
|
||||
return (
|
||||
input,
|
||||
Some(Token::CommentBlock(String::from_utf8_lossy(comment).to_string())),
|
||||
);
|
||||
} else if let Some(input) = eat(input, "/=") {
|
||||
return (input, Some(Token::DivEq));
|
||||
let len = if let Some(eol) = eol { eol + 4 } else { input.len() };
|
||||
return (len, Some(Token::CommentBlock(input_tendril.subtendril(0, len as u32))));
|
||||
} else if let Some(len) = eat(input, "/=") {
|
||||
return (len, Some(Token::DivEq));
|
||||
}
|
||||
return (&input[1..], Some(Token::Div));
|
||||
return (1, Some(Token::Div));
|
||||
}
|
||||
b':' => {
|
||||
if let Some(input) = eat(input, "::") {
|
||||
return (input, Some(Token::DoubleColon));
|
||||
if let Some(len) = eat(input, "::") {
|
||||
return (len, Some(Token::DoubleColon));
|
||||
} else {
|
||||
return (&input[1..], Some(Token::Colon));
|
||||
return (1, Some(Token::Colon));
|
||||
}
|
||||
}
|
||||
b';' => return (&input[1..], Some(Token::Semicolon)),
|
||||
b';' => return (1, Some(Token::Semicolon)),
|
||||
b'<' => {
|
||||
if let Some(input) = eat(input, "<=") {
|
||||
return (input, Some(Token::LtEq));
|
||||
} else if let Some(input) = eat(input, "<<") {
|
||||
if let Some(input) = eat(input, "=") {
|
||||
return (input, Some(Token::ShlEq));
|
||||
if let Some(len) = eat(input, "<=") {
|
||||
return (len, Some(Token::LtEq));
|
||||
} else if let Some(len) = eat(input, "<<") {
|
||||
if let Some(inner_len) = eat(&input[len..], "=") {
|
||||
return (len + inner_len, Some(Token::ShlEq));
|
||||
}
|
||||
return (input, Some(Token::Shl));
|
||||
return (len, Some(Token::Shl));
|
||||
}
|
||||
return (&input[1..], Some(Token::Lt));
|
||||
return (1, Some(Token::Lt));
|
||||
}
|
||||
b'>' => {
|
||||
if let Some(input) = eat(input, ">=") {
|
||||
return (input, Some(Token::GtEq));
|
||||
} else if let Some(input) = eat(input, ">>") {
|
||||
if let Some(input) = eat(input, "=") {
|
||||
return (input, Some(Token::ShrEq));
|
||||
} else if let Some(input) = eat(input, ">") {
|
||||
if let Some(input) = eat(input, "=") {
|
||||
return (input, Some(Token::ShrSignedEq));
|
||||
if let Some(len) = eat(input, ">=") {
|
||||
return (len, Some(Token::GtEq));
|
||||
} else if let Some(len) = eat(input, ">>") {
|
||||
if let Some(inner_len) = eat(&input[len..], "=") {
|
||||
return (len + inner_len, Some(Token::ShrEq));
|
||||
} else if let Some(inner_len) = eat(&input[len..], ">") {
|
||||
if let Some(eq_len) = eat(&input[len + inner_len..], "=") {
|
||||
return (len + inner_len + eq_len, Some(Token::ShrSignedEq));
|
||||
}
|
||||
return (input, Some(Token::ShrSigned));
|
||||
return (len + inner_len, Some(Token::ShrSigned));
|
||||
}
|
||||
return (input, Some(Token::Shr));
|
||||
return (len, Some(Token::Shr));
|
||||
}
|
||||
return (&input[1..], Some(Token::Gt));
|
||||
return (1, Some(Token::Gt));
|
||||
}
|
||||
b'=' => {
|
||||
if let Some(input) = eat(input, "==") {
|
||||
return (input, Some(Token::Eq));
|
||||
if let Some(len) = eat(input, "==") {
|
||||
return (len, Some(Token::Eq));
|
||||
}
|
||||
return (&input[1..], Some(Token::Assign));
|
||||
return (1, Some(Token::Assign));
|
||||
}
|
||||
b'@' => return (&input[1..], Some(Token::At)),
|
||||
b'[' => return (&input[1..], Some(Token::LeftSquare)),
|
||||
b']' => return (&input[1..], Some(Token::RightSquare)),
|
||||
b'{' => return (&input[1..], Some(Token::LeftCurly)),
|
||||
b'}' => return (&input[1..], Some(Token::RightCurly)),
|
||||
b'@' => return (1, Some(Token::At)),
|
||||
b'[' => return (1, Some(Token::LeftSquare)),
|
||||
b']' => return (1, Some(Token::RightSquare)),
|
||||
b'{' => return (1, Some(Token::LeftCurly)),
|
||||
b'}' => return (1, Some(Token::RightCurly)),
|
||||
b'|' => {
|
||||
if let Some(input) = eat(input, "||") {
|
||||
if let Some(input) = eat(input, "=") {
|
||||
return (input, Some(Token::OrEq));
|
||||
if let Some(len) = eat(input, "||") {
|
||||
if let Some(inner_len) = eat(&input[len..], "=") {
|
||||
return (len + inner_len, Some(Token::OrEq));
|
||||
}
|
||||
return (input, Some(Token::Or));
|
||||
} else if let Some(input) = eat(input, "|=") {
|
||||
return (input, Some(Token::BitOrEq));
|
||||
return (len, Some(Token::Or));
|
||||
} else if let Some(len) = eat(input, "|=") {
|
||||
return (len, Some(Token::BitOrEq));
|
||||
}
|
||||
return (&input[1..], Some(Token::BitOr));
|
||||
return (1, Some(Token::BitOr));
|
||||
}
|
||||
b'^' => {
|
||||
if let Some(input) = eat(input, "^=") {
|
||||
return (input, Some(Token::BitXorEq));
|
||||
if let Some(len) = eat(input, "^=") {
|
||||
return (len, Some(Token::BitXorEq));
|
||||
}
|
||||
return (&input[1..], Some(Token::BitXor));
|
||||
return (1, Some(Token::BitXor));
|
||||
}
|
||||
b'~' => return (&input[1..], Some(Token::BitNot)),
|
||||
b'~' => return (1, Some(Token::BitNot)),
|
||||
b'%' => {
|
||||
if let Some(input) = eat(input, "%=") {
|
||||
return (input, Some(Token::ModEq));
|
||||
if let Some(len) = eat(input, "%=") {
|
||||
return (len, Some(Token::ModEq));
|
||||
}
|
||||
return (&input[1..], Some(Token::Mod));
|
||||
return (1, Some(Token::Mod));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
if let Some((ident, input)) = eat_identifier(input) {
|
||||
let ident = String::from_utf8_lossy(ident).to_string();
|
||||
if let Some(ident) = eat_identifier(&input_tendril) {
|
||||
return (
|
||||
input,
|
||||
ident.len(),
|
||||
Some(match &*ident {
|
||||
x if x.starts_with("aleo1")
|
||||
&& x.chars().skip(5).all(|x| x.is_ascii_lowercase() || x.is_ascii_digit()) =>
|
||||
{
|
||||
Token::AddressLit(x.to_string())
|
||||
Token::AddressLit(ident)
|
||||
}
|
||||
"address" => Token::Address,
|
||||
"as" => Token::As,
|
||||
@ -358,7 +344,7 @@ impl Token {
|
||||
);
|
||||
}
|
||||
|
||||
(input, None)
|
||||
(0, None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,8 @@
|
||||
//! separated by whitespace.
|
||||
|
||||
pub(crate) mod token;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub(crate) use self::token::*;
|
||||
|
||||
pub(crate) mod lexer;
|
||||
@ -27,31 +29,33 @@ pub(crate) use self::lexer::*;
|
||||
|
||||
use crate::TokenError;
|
||||
use leo_ast::Span;
|
||||
|
||||
use std::rc::Rc;
|
||||
use tendril::StrTendril;
|
||||
|
||||
/// Creates a new vector of spanned tokens from a given file path and source code text.
|
||||
pub(crate) fn tokenize(path: &str, source: &str) -> Result<Vec<SpannedToken>, TokenError> {
|
||||
let path = Rc::new(path.to_string());
|
||||
let mut input = source.as_bytes();
|
||||
let mut tokens = Vec::new();
|
||||
pub(crate) fn tokenize(path: &str, input: StrTendril) -> Result<Vec<SpannedToken>, TokenError> {
|
||||
let path = Arc::new(path.to_string());
|
||||
let mut tokens = vec![];
|
||||
let mut index = 0usize;
|
||||
let mut line_no = 1usize;
|
||||
let mut line_start = 0usize;
|
||||
while !input.is_empty() {
|
||||
match Token::gobble(input) {
|
||||
(output, Some(token)) => {
|
||||
while input.len() > index {
|
||||
match Token::eat(input.subtendril(index as u32, (input.len() - index) as u32)) {
|
||||
(token_len, Some(token)) => {
|
||||
let mut span = Span {
|
||||
line_start: line_no,
|
||||
line_stop: line_no,
|
||||
col_start: index - line_start + 1,
|
||||
col_stop: index - line_start + (input.len() - output.len()) + 1,
|
||||
col_stop: index - line_start + token_len + 1,
|
||||
path: path.clone(),
|
||||
content: input.subtendril(
|
||||
line_start as u32,
|
||||
input[line_start..].find('\n').unwrap_or(input.len() - line_start) as u32,
|
||||
),
|
||||
};
|
||||
match &token {
|
||||
Token::CommentLine(_) => {
|
||||
line_no += 1;
|
||||
line_start = index + (input.len() - output.len());
|
||||
line_start = index + token_len;
|
||||
}
|
||||
Token::CommentBlock(block) => {
|
||||
let line_ct = block.chars().filter(|x| *x == '\n').count();
|
||||
@ -59,7 +63,7 @@ pub(crate) fn tokenize(path: &str, source: &str) -> Result<Vec<SpannedToken>, To
|
||||
if line_ct > 0 {
|
||||
let last_line_index = block.rfind('\n').unwrap();
|
||||
line_start = index + last_line_index + 1;
|
||||
span.col_stop = index + (input.len() - output.len()) - line_start + 1;
|
||||
span.col_stop = index + token_len - line_start + 1;
|
||||
}
|
||||
span.line_stop = line_no;
|
||||
}
|
||||
@ -71,30 +75,29 @@ pub(crate) fn tokenize(path: &str, source: &str) -> Result<Vec<SpannedToken>, To
|
||||
_ => (),
|
||||
}
|
||||
tokens.push(SpannedToken { token, span });
|
||||
index += input.len() - output.len();
|
||||
input = output;
|
||||
index += token_len;
|
||||
}
|
||||
(output, None) => {
|
||||
if output.is_empty() {
|
||||
(token_len, None) => {
|
||||
if token_len == 0 && index == input.len() {
|
||||
break;
|
||||
} else if output.len() == input.len() {
|
||||
return Err(TokenError::unexpected_token(
|
||||
&String::from_utf8_lossy(&[input[0]]),
|
||||
&Span {
|
||||
line_start: line_no,
|
||||
line_stop: line_no,
|
||||
col_start: index - line_start + 1,
|
||||
col_stop: index - line_start + 2,
|
||||
path,
|
||||
},
|
||||
));
|
||||
} else if token_len == 0 {
|
||||
return Err(TokenError::unexpected_token(&input[index..index + 1], &Span {
|
||||
line_start: line_no,
|
||||
line_stop: line_no,
|
||||
col_start: index - line_start + 1,
|
||||
col_stop: index - line_start + 2,
|
||||
path,
|
||||
content: input.subtendril(
|
||||
line_start as u32,
|
||||
input[line_start..].find('\n').unwrap_or_else(|| input.len()) as u32,
|
||||
),
|
||||
}));
|
||||
}
|
||||
index += input.len() - output.len();
|
||||
if input[0] == b'\n' {
|
||||
if input.as_bytes()[index] == b'\n' {
|
||||
line_no += 1;
|
||||
line_start = index;
|
||||
line_start = index + token_len;
|
||||
}
|
||||
input = output;
|
||||
index += token_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -212,18 +215,18 @@ mod tests {
|
||||
?
|
||||
// test
|
||||
/* test */
|
||||
//"#,
|
||||
//"#
|
||||
.into(),
|
||||
)
|
||||
.unwrap();
|
||||
let mut output = String::new();
|
||||
for SpannedToken { token, .. } in tokens.iter() {
|
||||
output += &format!("{} ", &token.to_string());
|
||||
output += &format!("{} ", token.to_string());
|
||||
}
|
||||
assert_eq!(
|
||||
output,
|
||||
r#""test" "test{}test" "test{}" "{}test" "test{" "test}" "test{test" "test}test" "te{{}}" aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8 test_ident 12345 address as bool circuit const else false field for function group i128 i64 i32 i16 i8 if import in input let mut return static string test true u128 u64 u32 u16 u8 self Self console ! != && ( ) * ** **= *= + += , - -= -> . .. ... / /= : :: ; < <= = == > >= @ [ ] { { } } || & &= | |= ^ ^= ~ << <<= >> >>= >>> >>>= % %= ||= &&= ? // test
|
||||
/* test */ //
|
||||
"#
|
||||
/* test */ // "#
|
||||
);
|
||||
}
|
||||
|
||||
@ -239,7 +242,7 @@ mod tests {
|
||||
test */
|
||||
test
|
||||
"#;
|
||||
let tokens = tokenize("test_path", raw).unwrap();
|
||||
let tokens = tokenize("test_path", raw.into()).unwrap();
|
||||
let mut line_indicies = vec![0];
|
||||
for (i, c) in raw.chars().enumerate() {
|
||||
if c == '\n' {
|
||||
|
@ -16,11 +16,12 @@
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use tendril::StrTendril;
|
||||
|
||||
/// Parts of a formatted string for logging to the console.
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum FormattedStringPart {
|
||||
Const(String),
|
||||
Const(#[serde(with = "leo_ast::common::tendril_json")] StrTendril),
|
||||
Container,
|
||||
}
|
||||
|
||||
@ -37,11 +38,11 @@ impl fmt::Display for FormattedStringPart {
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum Token {
|
||||
FormattedString(Vec<FormattedStringPart>),
|
||||
AddressLit(String),
|
||||
Ident(String),
|
||||
Int(String),
|
||||
CommentLine(String),
|
||||
CommentBlock(String),
|
||||
AddressLit(#[serde(with = "leo_ast::common::tendril_json")] StrTendril),
|
||||
Ident(#[serde(with = "leo_ast::common::tendril_json")] StrTendril),
|
||||
Int(#[serde(with = "leo_ast::common::tendril_json")] StrTendril),
|
||||
CommentLine(#[serde(with = "leo_ast::common::tendril_json")] StrTendril),
|
||||
CommentBlock(#[serde(with = "leo_ast::common::tendril_json")] StrTendril),
|
||||
Not,
|
||||
NotEq,
|
||||
And,
|
||||
@ -193,7 +194,7 @@ impl fmt::Display for Token {
|
||||
AddressLit(s) => write!(f, "{}", s),
|
||||
Ident(s) => write!(f, "{}", s),
|
||||
Int(s) => write!(f, "{}", s),
|
||||
CommentLine(s) => writeln!(f, "{}", s),
|
||||
CommentLine(s) => write!(f, "{}", s),
|
||||
CommentBlock(s) => write!(f, "{}", s),
|
||||
Not => write!(f, "!"),
|
||||
NotEq => write!(f, "!="),
|
||||
|
@ -4,9 +4,9 @@
|
||||
"imports": [],
|
||||
"circuits": {},
|
||||
"functions": {
|
||||
"{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"test\\\"}\"}": {
|
||||
"{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"function main() {\\\"}\"}": {
|
||||
"annotations": [],
|
||||
"identifier": "{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"test\\\"}\"}",
|
||||
"identifier": "{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"function main() {\\\"}\"}",
|
||||
"input": [],
|
||||
"output": null,
|
||||
"block": {
|
||||
@ -24,7 +24,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 12,
|
||||
"col_stop": 13,
|
||||
"path": "test"
|
||||
"path": "test",
|
||||
"content": " return 1 + 1"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -38,7 +39,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 16,
|
||||
"col_stop": 17,
|
||||
"path": "test"
|
||||
"path": "test",
|
||||
"content": " return 1 + 1"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -49,7 +51,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 12,
|
||||
"col_stop": 17,
|
||||
"path": "test"
|
||||
"path": "test",
|
||||
"content": " return 1 + 1"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -58,7 +61,8 @@
|
||||
"line_stop": 2,
|
||||
"col_start": 5,
|
||||
"col_stop": 17,
|
||||
"path": "test"
|
||||
"path": "test",
|
||||
"content": " return 1 + 1"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -68,7 +72,8 @@
|
||||
"line_stop": 3,
|
||||
"col_start": 17,
|
||||
"col_stop": 2,
|
||||
"path": "test"
|
||||
"path": "test",
|
||||
"content": "function main() {\n...\n}"
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
@ -76,7 +81,8 @@
|
||||
"line_stop": 3,
|
||||
"col_start": 1,
|
||||
"col_stop": 2,
|
||||
"path": "test"
|
||||
"path": "test",
|
||||
"content": "function main() {\n...\n}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ pub fn find_input(
|
||||
) -> Result<InputValue, InputValueError> {
|
||||
let matched_parameter = parameters
|
||||
.iter()
|
||||
.find(|(parameter, _value)| parameter.variable.name == name);
|
||||
.find(|(parameter, _value)| parameter.variable.name.as_ref() == name);
|
||||
|
||||
match matched_parameter {
|
||||
Some((_, Some(value))) => Ok(value.clone()),
|
||||
|
Loading…
Reference in New Issue
Block a user