mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-23 07:07:07 +03:00
Update AST
This commit is contained in:
parent
4a3e89f877
commit
bc7e6c3fa2
159
compiler/ast/src/expressions/locator.rs
Normal file
159
compiler/ast/src/expressions/locator.rs
Normal file
@ -0,0 +1,159 @@
|
||||
// Copyright (C) 2019-2023 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 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 std::{
|
||||
collections::BTreeMap,
|
||||
fmt,
|
||||
hash::{Hash, Hasher},
|
||||
};
|
||||
|
||||
/// A locator that references an external resource.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct LocatorExpression {
|
||||
/// The program that the resource is in.
|
||||
pub program: Symbol,
|
||||
/// The name of the resource.
|
||||
pub name: Symbol,
|
||||
/// A span indicating where the locator occurred in the source.
|
||||
pub span: Span,
|
||||
/// The ID of the node.
|
||||
pub id: NodeID,
|
||||
}
|
||||
|
||||
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 {
|
||||
Self { program, name, span: Span::default(), id }
|
||||
}
|
||||
|
||||
/// Check if the Locator name and program matches the other name and program.
|
||||
pub fn matches(&self, other: &Self) -> bool {
|
||||
self.name == other.name && self.program == other.program
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for LocatorExpression {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}.aleo/{}", 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)
|
||||
}
|
||||
}
|
@ -56,6 +56,9 @@ pub use unit::*;
|
||||
mod literal;
|
||||
pub use literal::*;
|
||||
|
||||
pub mod locator;
|
||||
pub use locator::*;
|
||||
|
||||
/// Expression that evaluates to a value.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum Expression {
|
||||
@ -69,8 +72,6 @@ pub enum Expression {
|
||||
Call(CallExpression),
|
||||
/// A cast expression, e.g., `42u32 as u8`.
|
||||
Cast(CastExpression),
|
||||
/// An expression constructing a struct like `Foo { bar: 42, baz }`.
|
||||
Struct(StructExpression),
|
||||
/// An expression of type "error".
|
||||
/// Will result in a compile error eventually.
|
||||
Err(ErrExpression),
|
||||
@ -78,6 +79,10 @@ pub enum Expression {
|
||||
Identifier(Identifier),
|
||||
/// A literal expression.
|
||||
Literal(Literal),
|
||||
/// A locator expression, e.g., `hello.aleo/foo`.
|
||||
Locator(LocatorExpression),
|
||||
/// An expression constructing a struct like `Foo { bar: 42, baz }`.
|
||||
Struct(StructExpression),
|
||||
/// A ternary conditional expression `cond ? if_expr : else_expr`.
|
||||
Ternary(TernaryExpression),
|
||||
/// A tuple expression e.g., `(foo, 42, true)`.
|
||||
@ -97,10 +102,11 @@ impl Node for Expression {
|
||||
Binary(n) => n.span(),
|
||||
Call(n) => n.span(),
|
||||
Cast(n) => n.span(),
|
||||
Struct(n) => n.span(),
|
||||
Err(n) => n.span(),
|
||||
Identifier(n) => n.span(),
|
||||
Literal(n) => n.span(),
|
||||
Locator(n) => n.span(),
|
||||
Struct(n) => n.span(),
|
||||
Ternary(n) => n.span(),
|
||||
Tuple(n) => n.span(),
|
||||
Unary(n) => n.span(),
|
||||
@ -116,10 +122,11 @@ impl Node for Expression {
|
||||
Binary(n) => n.set_span(span),
|
||||
Call(n) => n.set_span(span),
|
||||
Cast(n) => n.set_span(span),
|
||||
Struct(n) => n.set_span(span),
|
||||
Identifier(n) => n.set_span(span),
|
||||
Literal(n) => n.set_span(span),
|
||||
Locator(n) => n.set_span(span),
|
||||
Err(n) => n.set_span(span),
|
||||
Struct(n) => n.set_span(span),
|
||||
Ternary(n) => n.set_span(span),
|
||||
Tuple(n) => n.set_span(span),
|
||||
Unary(n) => n.set_span(span),
|
||||
@ -135,10 +142,11 @@ impl Node for Expression {
|
||||
Binary(n) => n.id(),
|
||||
Call(n) => n.id(),
|
||||
Cast(n) => n.id(),
|
||||
Struct(n) => n.id(),
|
||||
Identifier(n) => n.id(),
|
||||
Literal(n) => n.id(),
|
||||
Locator(n) => n.id(),
|
||||
Err(n) => n.id(),
|
||||
Struct(n) => n.id(),
|
||||
Ternary(n) => n.id(),
|
||||
Tuple(n) => n.id(),
|
||||
Unary(n) => n.id(),
|
||||
@ -154,10 +162,11 @@ impl Node for Expression {
|
||||
Binary(n) => n.set_id(id),
|
||||
Call(n) => n.set_id(id),
|
||||
Cast(n) => n.set_id(id),
|
||||
Struct(n) => n.set_id(id),
|
||||
Identifier(n) => n.set_id(id),
|
||||
Literal(n) => n.set_id(id),
|
||||
Locator(n) => n.set_id(id),
|
||||
Err(n) => n.set_id(id),
|
||||
Struct(n) => n.set_id(id),
|
||||
Ternary(n) => n.set_id(id),
|
||||
Tuple(n) => n.set_id(id),
|
||||
Unary(n) => n.set_id(id),
|
||||
@ -175,10 +184,11 @@ impl fmt::Display for Expression {
|
||||
Binary(n) => n.fmt(f),
|
||||
Call(n) => n.fmt(f),
|
||||
Cast(n) => n.fmt(f),
|
||||
Struct(n) => n.fmt(f),
|
||||
Err(n) => n.fmt(f),
|
||||
Identifier(n) => n.fmt(f),
|
||||
Literal(n) => n.fmt(f),
|
||||
Locator(n) => n.fmt(f),
|
||||
Struct(n) => n.fmt(f),
|
||||
Ternary(n) => n.fmt(f),
|
||||
Tuple(n) => n.fmt(f),
|
||||
Unary(n) => n.fmt(f),
|
||||
|
@ -34,6 +34,7 @@ pub trait ExpressionConsumer {
|
||||
Expression::Err(err) => self.consume_err(err),
|
||||
Expression::Identifier(identifier) => self.consume_identifier(identifier),
|
||||
Expression::Literal(value) => self.consume_literal(value),
|
||||
Expression::Locator(locator) => self.consume_locator(locator),
|
||||
Expression::Ternary(ternary) => self.consume_ternary(ternary),
|
||||
Expression::Tuple(tuple) => self.consume_tuple(tuple),
|
||||
Expression::Unary(unary) => self.consume_unary(unary),
|
||||
@ -60,6 +61,8 @@ pub trait ExpressionConsumer {
|
||||
fn consume_identifier(&mut self, _input: Identifier) -> Self::Output;
|
||||
|
||||
fn consume_literal(&mut self, _input: Literal) -> Self::Output;
|
||||
|
||||
fn consume_locator(&mut self, _input: LocatorExpression) -> Self::Output;
|
||||
|
||||
fn consume_ternary(&mut self, _input: TernaryExpression) -> Self::Output;
|
||||
|
||||
|
@ -35,6 +35,7 @@ pub trait ExpressionReconstructor {
|
||||
Expression::Err(err) => self.reconstruct_err(err),
|
||||
Expression::Identifier(identifier) => self.reconstruct_identifier(identifier),
|
||||
Expression::Literal(value) => self.reconstruct_literal(value),
|
||||
Expression::Locator(locator) => self.reconstruct_locator(locator),
|
||||
Expression::Ternary(ternary) => self.reconstruct_ternary(ternary),
|
||||
Expression::Tuple(tuple) => self.reconstruct_tuple(tuple),
|
||||
Expression::Unary(unary) => self.reconstruct_unary(unary),
|
||||
@ -197,6 +198,13 @@ pub trait ExpressionReconstructor {
|
||||
fn reconstruct_literal(&mut self, input: Literal) -> (Expression, Self::AdditionalOutput) {
|
||||
(Expression::Literal(input), Default::default())
|
||||
}
|
||||
|
||||
fn reconstruct_locator(&mut self, input: LocatorExpression) -> (Expression, Self::AdditionalOutput) {
|
||||
(
|
||||
Expression::Locator(input),
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
|
||||
fn reconstruct_ternary(&mut self, input: TernaryExpression) -> (Expression, Self::AdditionalOutput) {
|
||||
(
|
||||
|
@ -36,6 +36,7 @@ pub trait ExpressionVisitor<'a> {
|
||||
Expression::Err(err) => self.visit_err(err, additional),
|
||||
Expression::Identifier(identifier) => self.visit_identifier(identifier, additional),
|
||||
Expression::Literal(literal) => self.visit_literal(literal, additional),
|
||||
Expression::Locator(locator) => self.visit_locator(locator, additional),
|
||||
Expression::Ternary(ternary) => self.visit_ternary(ternary, additional),
|
||||
Expression::Tuple(tuple) => self.visit_tuple(tuple, additional),
|
||||
Expression::Unary(unary) => self.visit_unary(unary, additional),
|
||||
@ -106,6 +107,10 @@ pub trait ExpressionVisitor<'a> {
|
||||
fn visit_literal(&mut self, _input: &'a Literal, _additional: &Self::AdditionalInput) -> Self::Output {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_locator(&mut self, input: &'a LocatorExpression, additional: &Self::AdditionalInput) -> Self::Output {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_ternary(&mut self, input: &'a TernaryExpression, additional: &Self::AdditionalInput) -> Self::Output {
|
||||
self.visit_expression(&input.condition, additional);
|
||||
|
@ -18,12 +18,14 @@ use crate::Type;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use leo_span::Symbol;
|
||||
|
||||
/// A mapping type of a key and value type.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct MappingType {
|
||||
pub key: Box<Type>,
|
||||
pub value: Box<Type>,
|
||||
pub program: Symbol,
|
||||
}
|
||||
|
||||
impl fmt::Display for MappingType {
|
||||
|
Loading…
Reference in New Issue
Block a user