mirror of
https://github.com/AleoHQ/leo.git
synced 2024-09-21 03:57:39 +03:00
Refactor LocatorExpression
This commit is contained in:
parent
a92e2814c4
commit
94b5d927d7
@ -14,31 +14,20 @@
|
||||
// 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 leo_errors::Result;
|
||||
use leo_span::{Span, Symbol};
|
||||
|
||||
use crate::{simple_node_impl, Node, NodeID};
|
||||
use serde::{
|
||||
de::{
|
||||
Visitor,
|
||||
{self},
|
||||
},
|
||||
Deserialize,
|
||||
Deserializer,
|
||||
Serialize,
|
||||
Serializer,
|
||||
};
|
||||
use crate::{simple_node_impl, Node, NodeID, ProgramId};
|
||||
use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::{
|
||||
collections::BTreeMap,
|
||||
fmt,
|
||||
hash::{Hash, Hasher},
|
||||
};
|
||||
|
||||
/// A locator that references an external resource.
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct LocatorExpression {
|
||||
/// The program that the resource is in.
|
||||
pub program: Symbol,
|
||||
pub program: ProgramId,
|
||||
/// The name of the resource.
|
||||
pub name: Symbol,
|
||||
/// A span indicating where the locator occurred in the source.
|
||||
@ -51,7 +40,7 @@ simple_node_impl!(LocatorExpression);
|
||||
|
||||
impl LocatorExpression {
|
||||
/// Constructs a new Locator with `name`, `program` and `id` and a default span.
|
||||
pub fn new(program: Symbol, name: Symbol, id: NodeID) -> Self {
|
||||
pub fn new(program: ProgramId, name: Symbol, id: NodeID) -> Self {
|
||||
Self { program, name, span: Span::default(), id }
|
||||
}
|
||||
|
||||
@ -63,97 +52,11 @@ impl LocatorExpression {
|
||||
|
||||
impl fmt::Display for LocatorExpression {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}.aleo/{}", self.program, self.name)
|
||||
write!(f, "{}/{}", self.program, self.name)
|
||||
}
|
||||
}
|
||||
impl fmt::Debug for LocatorExpression {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}.aleo/{}", self.program, self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for LocatorExpression {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.name == other.name && self.program == other.program && self.span == other.span
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for LocatorExpression {}
|
||||
|
||||
impl Hash for LocatorExpression {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.name.hash(state);
|
||||
self.program.hash(state);
|
||||
self.span.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for LocatorExpression {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
// Converts an element that implements Serialize into a string.
|
||||
fn to_json_string<E: Serialize, Error: serde::ser::Error>(element: &E) -> Result<String, Error> {
|
||||
serde_json::to_string(&element).map_err(|e| Error::custom(e.to_string()))
|
||||
}
|
||||
|
||||
// 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.to_string());
|
||||
key.insert("program".to_string(), self.program.to_string());
|
||||
key.insert("span".to_string(), to_json_string(&self.span)?);
|
||||
key.insert("id".to_string(), to_json_string(&self.id)?);
|
||||
|
||||
// Convert the serialized object into a string for use as a key.
|
||||
serializer.serialize_str(&to_json_string(&key)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for LocatorExpression {
|
||||
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||
struct LocatorVisitor;
|
||||
|
||||
impl Visitor<'_> for LocatorVisitor {
|
||||
type Value = LocatorExpression;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a string encoding the ast Identifier struct")
|
||||
}
|
||||
|
||||
/// Implementation for recovering a string that serializes Locator.
|
||||
fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
|
||||
// Converts a serialized string into an element that implements Deserialize.
|
||||
fn to_json_string<'a, D: Deserialize<'a>, Error: serde::de::Error>(
|
||||
serialized: &'a str,
|
||||
) -> Result<D, Error> {
|
||||
serde_json::from_str::<'a>(serialized).map_err(|e| Error::custom(e.to_string()))
|
||||
}
|
||||
|
||||
// Convert the serialized string into a BTreeMap to recover Locator.
|
||||
let key: BTreeMap<String, String> = to_json_string(value)?;
|
||||
|
||||
let name = match key.get("name") {
|
||||
Some(name) => Symbol::intern(name),
|
||||
None => return Err(E::custom("missing 'name' in serialized Identifier struct")),
|
||||
};
|
||||
|
||||
let program = match key.get("program") {
|
||||
Some(program) => Symbol::intern(program),
|
||||
None => return Err(E::custom("missing 'program' in serialized Identifier struct")),
|
||||
};
|
||||
|
||||
let span: Span = match key.get("span") {
|
||||
Some(span) => to_json_string(span)?,
|
||||
None => return Err(E::custom("missing 'span' in serialized Identifier struct")),
|
||||
};
|
||||
|
||||
let id: NodeID = match key.get("id") {
|
||||
Some(id) => to_json_string(id)?,
|
||||
None => return Err(E::custom("missing 'id' in serialized Identifier struct")),
|
||||
};
|
||||
|
||||
Ok(LocatorExpression { program, name, span, id })
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_str(LocatorVisitor)
|
||||
write!(f, "{}/{}", self.program, self.name)
|
||||
}
|
||||
}
|
||||
|
@ -430,7 +430,7 @@ impl ParserContext<'_> {
|
||||
}
|
||||
|
||||
// Parses an external function call `credits.aleo/transfer()` or locator `token.aleo/accounts`.
|
||||
fn parse_external_resource(&mut self, expr: Expression) -> Result<Expression> {
|
||||
fn parse_external_resource(&mut self, expr: Expression, network_span: Span) -> Result<Expression> {
|
||||
// Eat an external function call.
|
||||
self.eat(&Token::Div); // todo: Make `/` a more general token.
|
||||
|
||||
@ -438,8 +438,8 @@ impl ParserContext<'_> {
|
||||
let name = self.expect_identifier()?;
|
||||
|
||||
// Parse the parent program identifier.
|
||||
let program: Symbol = match expr {
|
||||
Expression::Identifier(identifier) => identifier.name,
|
||||
let program: Identifier = match expr {
|
||||
Expression::Identifier(identifier) => identifier,
|
||||
_ => unreachable!("Function called must be preceded by a program identifier."),
|
||||
};
|
||||
|
||||
@ -452,7 +452,10 @@ impl ParserContext<'_> {
|
||||
if self.token.token != Token::LeftParen {
|
||||
// Parse an external resource locator.
|
||||
return Ok(Expression::Locator(LocatorExpression {
|
||||
program,
|
||||
program: ProgramId {
|
||||
name: program,
|
||||
network: Identifier { name: sym::aleo, span: network_span, id: self.node_builder.next_id() },
|
||||
},
|
||||
name: name.name,
|
||||
span: expr.span() + name.span(),
|
||||
id: self.node_builder.next_id(),
|
||||
@ -465,7 +468,7 @@ impl ParserContext<'_> {
|
||||
Ok(Expression::Call(CallExpression {
|
||||
span: expr.span() + span,
|
||||
function: Box::new(Expression::Identifier(name)),
|
||||
program: Some(program),
|
||||
program: Some(program.name),
|
||||
arguments,
|
||||
id: self.node_builder.next_id(),
|
||||
}))
|
||||
@ -494,7 +497,7 @@ impl ParserContext<'_> {
|
||||
} else if self.eat(&Token::Leo) {
|
||||
return Err(ParserError::only_aleo_external_calls(expr.span()).into());
|
||||
} else if self.eat(&Token::Aleo) {
|
||||
expr = self.parse_external_resource(expr)?;
|
||||
expr = self.parse_external_resource(expr, self.prev_token.span)?;
|
||||
} else {
|
||||
// Parse identifier name.
|
||||
let name = self.expect_identifier()?;
|
||||
|
@ -771,7 +771,9 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
|
||||
|
||||
fn visit_locator(&mut self, input: &'a LocatorExpression, expected: &Self::AdditionalInput) -> Self::Output {
|
||||
// Check that the locator points to a valid resource in the ST.
|
||||
if let Some(var) = self.symbol_table.borrow().lookup_variable(Location::new(Some(input.program), input.name)) {
|
||||
if let Some(var) =
|
||||
self.symbol_table.borrow().lookup_variable(Location::new(Some(input.program.name.name), input.name))
|
||||
{
|
||||
Some(self.assert_and_return_type(var.type_.clone(), expected, input.span()))
|
||||
} else {
|
||||
self.emit_err(TypeCheckerError::unknown_sym("variable", input.name, input.span()));
|
||||
|
@ -16,16 +16,16 @@ outputs:
|
||||
bytecode: c44dd5a8d2158e3729310c6e423739cde6f4f8261609820886f26aa09afe707b
|
||||
errors: ""
|
||||
warnings: ""
|
||||
- initial_symbol_table: f1bdf4ae2702708d6d85ba318ad8ff9808124a83f107a19b15f4d30e167e6d11
|
||||
type_checked_symbol_table: d687b1f3c123bda116691c0b5a1b9a1895f20fa0d88511473a0881fe749ef9b7
|
||||
unrolled_symbol_table: d687b1f3c123bda116691c0b5a1b9a1895f20fa0d88511473a0881fe749ef9b7
|
||||
initial_ast: f4f8e8eb75a9ae12e391ee4107b0fd10a2013e768d1ecb742b636b554baf7ae6
|
||||
unrolled_ast: 365df4c78ec80b1018c3916d6c6c5f166a973ec95f6312b2215e3aa44b6dfef9
|
||||
ssa_ast: 94499ab484cb507a2a09279e4adbeea903a418ef516cb0a13fadf41e26482a3b
|
||||
flattened_ast: 41167a9098ff4dcdb91390effc77000faa121a41cd1f4d056f994c8a09f80c28
|
||||
destructured_ast: 604f5ded275781d99f1b6bcc7443a8b1cadb30c8cce0ccc8abf66b7acc77fc6d
|
||||
inlined_ast: 604f5ded275781d99f1b6bcc7443a8b1cadb30c8cce0ccc8abf66b7acc77fc6d
|
||||
dce_ast: 604f5ded275781d99f1b6bcc7443a8b1cadb30c8cce0ccc8abf66b7acc77fc6d
|
||||
- initial_symbol_table: fbe7b97bd85bd4d788d8973a17a73ef63cb42b389639ee166301a6928d9aa429
|
||||
type_checked_symbol_table: f712c16610a96ec846141df4068ade8878ddfd8bebc4d1e182b69a4a2b6c81fe
|
||||
unrolled_symbol_table: f712c16610a96ec846141df4068ade8878ddfd8bebc4d1e182b69a4a2b6c81fe
|
||||
initial_ast: 443e7342407db51c493d0b22ac4a678c3dec2d285600c58c90f045987d88c683
|
||||
unrolled_ast: 4d735be74cb434f8e080c4ff9f53585ff7552e7e6974237afb19ebb23b8930de
|
||||
ssa_ast: c39b19084cdfbc1f78aaeaaa6ddac65d0278cf7c6364427c874015609a710544
|
||||
flattened_ast: a53f8520f941543dcf9faa21c9de585b2331ebacc062a20855fc809c23087da2
|
||||
destructured_ast: 05e43dddfc454213755f457a4acb3bf165dab99980811c0ed8d6e959439304c2
|
||||
inlined_ast: 05e43dddfc454213755f457a4acb3bf165dab99980811c0ed8d6e959439304c2
|
||||
dce_ast: 05e43dddfc454213755f457a4acb3bf165dab99980811c0ed8d6e959439304c2
|
||||
bytecode: 1260b31fff8f93549822bd3a3bba846b38ca6dd13eacaf908842384748b4ea4c
|
||||
errors: ""
|
||||
warnings: ""
|
||||
|
Loading…
Reference in New Issue
Block a user