mirror of
https://github.com/AleoHQ/leo.git
synced 2024-12-19 07:32:26 +03:00
staging commit for the sizeof operator
This commit is contained in:
parent
d2f63432f8
commit
2942bf85fe
@ -65,6 +65,9 @@ pub use variable_ref::*;
|
||||
mod cast;
|
||||
pub use cast::*;
|
||||
|
||||
mod sizeof;
|
||||
pub use sizeof::*;
|
||||
|
||||
use crate::{ConstValue, FromAst, Node, PartialType, Scope, Type};
|
||||
use leo_errors::{Result, Span};
|
||||
|
||||
@ -76,6 +79,7 @@ pub enum Expression<'a> {
|
||||
Unary(UnaryExpression<'a>),
|
||||
Ternary(TernaryExpression<'a>),
|
||||
Cast(CastExpression<'a>),
|
||||
SizeOf(SizeOfExpression<'a>),
|
||||
|
||||
ArrayInline(ArrayInlineExpression<'a>),
|
||||
ArrayInit(ArrayInitExpression<'a>),
|
||||
@ -107,6 +111,7 @@ impl<'a> Node for Expression<'a> {
|
||||
Unary(x) => x.span(),
|
||||
Ternary(x) => x.span(),
|
||||
Cast(x) => x.span(),
|
||||
SizeOf(x) => x.span(),
|
||||
ArrayInline(x) => x.span(),
|
||||
ArrayInit(x) => x.span(),
|
||||
ArrayAccess(x) => x.span(),
|
||||
@ -141,6 +146,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> {
|
||||
Unary(x) => x.set_parent(parent),
|
||||
Ternary(x) => x.set_parent(parent),
|
||||
Cast(x) => x.set_parent(parent),
|
||||
SizeOf(x) => x.set_parent(parent),
|
||||
ArrayInline(x) => x.set_parent(parent),
|
||||
ArrayInit(x) => x.set_parent(parent),
|
||||
ArrayAccess(x) => x.set_parent(parent),
|
||||
@ -162,6 +168,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> {
|
||||
Unary(x) => x.get_parent(),
|
||||
Ternary(x) => x.get_parent(),
|
||||
Cast(x) => x.get_parent(),
|
||||
SizeOf(x) => x.get_parent(),
|
||||
ArrayInline(x) => x.get_parent(),
|
||||
ArrayInit(x) => x.get_parent(),
|
||||
ArrayAccess(x) => x.get_parent(),
|
||||
@ -183,6 +190,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> {
|
||||
Unary(x) => x.enforce_parents(expr),
|
||||
Ternary(x) => x.enforce_parents(expr),
|
||||
Cast(x) => x.enforce_parents(expr),
|
||||
SizeOf(x) => x.enforce_parents(expr),
|
||||
ArrayInline(x) => x.enforce_parents(expr),
|
||||
ArrayInit(x) => x.enforce_parents(expr),
|
||||
ArrayAccess(x) => x.enforce_parents(expr),
|
||||
@ -204,6 +212,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> {
|
||||
Unary(x) => x.get_type(),
|
||||
Ternary(x) => x.get_type(),
|
||||
Cast(x) => x.get_type(),
|
||||
SizeOf(x) => x.get_type(),
|
||||
ArrayInline(x) => x.get_type(),
|
||||
ArrayInit(x) => x.get_type(),
|
||||
ArrayAccess(x) => x.get_type(),
|
||||
@ -225,6 +234,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> {
|
||||
Unary(x) => x.is_mut_ref(),
|
||||
Ternary(x) => x.is_mut_ref(),
|
||||
Cast(x) => x.is_mut_ref(),
|
||||
SizeOf(x) => x.is_mut_ref(),
|
||||
ArrayInline(x) => x.is_mut_ref(),
|
||||
ArrayInit(x) => x.is_mut_ref(),
|
||||
ArrayAccess(x) => x.is_mut_ref(),
|
||||
@ -246,6 +256,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> {
|
||||
Unary(x) => x.const_value(),
|
||||
Ternary(x) => x.const_value(),
|
||||
Cast(x) => x.const_value(),
|
||||
SizeOf(x) => x.const_value(),
|
||||
ArrayInline(x) => x.const_value(),
|
||||
ArrayInit(x) => x.const_value(),
|
||||
ArrayAccess(x) => x.const_value(),
|
||||
@ -267,6 +278,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> {
|
||||
Unary(x) => x.is_consty(),
|
||||
Ternary(x) => x.is_consty(),
|
||||
Cast(x) => x.is_consty(),
|
||||
SizeOf(x) => x.is_consty(),
|
||||
ArrayInline(x) => x.is_consty(),
|
||||
ArrayInit(x) => x.is_consty(),
|
||||
ArrayAccess(x) => x.is_consty(),
|
||||
@ -305,6 +317,10 @@ impl<'a> FromAst<'a, leo_ast::Expression> for &'a Expression<'a> {
|
||||
.context
|
||||
.alloc_expression(CastExpression::from_ast(scope, cast, expected_type).map(Expression::Cast)?),
|
||||
|
||||
SizeOf(sizeof) => scope
|
||||
.context
|
||||
.alloc_expression(SizeOfExpression::from_ast(scope, sizeof, expected_type).map(Expression::SizeOf)?),
|
||||
|
||||
ArrayInline(array_inline) => scope.context.alloc_expression(
|
||||
ArrayInlineExpression::from_ast(scope, array_inline, expected_type).map(Expression::ArrayInline)?,
|
||||
),
|
||||
@ -357,6 +373,7 @@ impl<'a> Into<leo_ast::Expression> for &Expression<'a> {
|
||||
Unary(x) => leo_ast::Expression::Unary(x.into()),
|
||||
Ternary(x) => leo_ast::Expression::Ternary(x.into()),
|
||||
Cast(x) => leo_ast::Expression::Cast(x.into()),
|
||||
SizeOf(x) => leo_ast::Expression::SizeOf(x.into()),
|
||||
ArrayInline(x) => leo_ast::Expression::ArrayInline(x.into()),
|
||||
ArrayInit(x) => leo_ast::Expression::ArrayInit(x.into()),
|
||||
ArrayAccess(x) => leo_ast::Expression::ArrayAccess(x.into()),
|
||||
|
102
asg/src/expression/sizeof.rs
Normal file
102
asg/src/expression/sizeof.rs
Normal file
@ -0,0 +1,102 @@
|
||||
// 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 crate::{ConstValue, Expression, ExpressionNode, FromAst, IntegerType, Node, PartialType, Scope, Type};
|
||||
pub use leo_ast::UnaryOperation;
|
||||
use leo_errors::{Result, Span};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SizeOfExpression<'a> {
|
||||
pub parent: Cell<Option<&'a Expression<'a>>>,
|
||||
pub span: Option<Span>,
|
||||
pub inner: Cell<&'a Expression<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> Node for SizeOfExpression<'a> {
|
||||
fn span(&self) -> Option<&Span> {
|
||||
self.span.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ExpressionNode<'a> for SizeOfExpression<'a> {
|
||||
fn set_parent(&self, parent: &'a Expression<'a>) {
|
||||
self.parent.replace(Some(parent));
|
||||
}
|
||||
|
||||
fn get_parent(&self) -> Option<&'a Expression<'a>> {
|
||||
self.parent.get()
|
||||
}
|
||||
|
||||
fn enforce_parents(&self, expr: &'a Expression<'a>) {
|
||||
self.inner.get().set_parent(expr);
|
||||
}
|
||||
|
||||
fn get_type(&self) -> Option<Type<'a>> {
|
||||
// TODO: make decision on get type method
|
||||
// Should it be always u32? For indexes?
|
||||
// How type casts are applied to this?
|
||||
Some(Type::Integer(IntegerType::U32))
|
||||
}
|
||||
|
||||
fn is_mut_ref(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn const_value(&self) -> Option<ConstValue> {
|
||||
let _value = self.inner.get().const_value()?;
|
||||
// match value {
|
||||
// ConstValue::Int(int) => match &self.target_type {
|
||||
// Type::Integer(target) => Some(ConstValue::Int(int.cast_to(target))),
|
||||
// _ => None,
|
||||
// },
|
||||
// _ => None,
|
||||
// }
|
||||
|
||||
// TODO: IMPLEMENT CONST VALUE
|
||||
None
|
||||
}
|
||||
|
||||
fn is_consty(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromAst<'a, leo_ast::SizeOfExpression> for SizeOfExpression<'a> {
|
||||
fn from_ast(
|
||||
scope: &'a Scope<'a>,
|
||||
value: &leo_ast::SizeOfExpression,
|
||||
_expected_type: Option<PartialType<'a>>,
|
||||
) -> Result<SizeOfExpression<'a>> {
|
||||
let inner = <&Expression<'a>>::from_ast(scope, &*value.inner, None)?;
|
||||
|
||||
Ok(SizeOfExpression {
|
||||
parent: Cell::new(None),
|
||||
span: Some(value.span.clone()),
|
||||
inner: Cell::new(inner),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Into<leo_ast::SizeOfExpression> for &SizeOfExpression<'a> {
|
||||
fn into(self) -> leo_ast::SizeOfExpression {
|
||||
leo_ast::SizeOfExpression {
|
||||
inner: Box::new(self.inner.get().into()),
|
||||
span: self.span.clone().unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
}
|
@ -48,6 +48,7 @@ impl<'a, T: Monoid, R: MonoidalReducerExpression<'a, T>> MonoidalDirector<'a, T,
|
||||
Expression::CircuitInit(e) => self.reduce_circuit_init(e),
|
||||
Expression::Ternary(e) => self.reduce_ternary_expression(e),
|
||||
Expression::Cast(e) => self.reduce_cast_expression(e),
|
||||
Expression::SizeOf(e) => self.reduce_sizeof_expression(e),
|
||||
Expression::Constant(e) => self.reduce_constant(e),
|
||||
Expression::TupleAccess(e) => self.reduce_tuple_access(e),
|
||||
Expression::TupleInit(e) => self.reduce_tuple_init(e),
|
||||
@ -138,6 +139,12 @@ impl<'a, T: Monoid, R: MonoidalReducerExpression<'a, T>> MonoidalDirector<'a, T,
|
||||
self.reducer.reduce_cast_expression(input, inner)
|
||||
}
|
||||
|
||||
pub fn reduce_sizeof_expression(&mut self, input: &SizeOfExpression<'a>) -> T {
|
||||
let inner = self.reduce_expression(input.inner.get());
|
||||
|
||||
self.reducer.reduce_sizeof_expression(input, inner)
|
||||
}
|
||||
|
||||
pub fn reduce_constant(&mut self, input: &Constant<'a>) -> T {
|
||||
self.reducer.reduce_constant(input)
|
||||
}
|
||||
|
@ -68,6 +68,10 @@ pub trait MonoidalReducerExpression<'a, T: Monoid> {
|
||||
inner
|
||||
}
|
||||
|
||||
fn reduce_sizeof_expression(&mut self, input: &SizeOfExpression<'a>, inner: T) -> T {
|
||||
inner
|
||||
}
|
||||
|
||||
fn reduce_constant(&mut self, input: &Constant<'a>) -> T {
|
||||
T::default()
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ impl<'a, R: ReconstructingReducerExpression<'a>> ReconstructingDirector<'a, R> {
|
||||
Expression::CircuitInit(e) => self.reduce_circuit_init(e),
|
||||
Expression::Ternary(e) => self.reduce_ternary_expression(e),
|
||||
Expression::Cast(e) => self.reduce_cast_expression(e),
|
||||
Expression::SizeOf(e) => Expression::SizeOf(e), //self.reduce_sizeof_expression(e), // TODO: implement REDUCER
|
||||
Expression::Constant(e) => self.reduce_constant(e),
|
||||
Expression::TupleAccess(e) => self.reduce_tuple_access(e),
|
||||
Expression::TupleInit(e) => self.reduce_tuple_init(e),
|
||||
|
@ -76,6 +76,10 @@ pub trait ExpressionVisitor<'a> {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_sizeof_expression(&mut self, input: &SizeOfExpression<'a>) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_constant(&mut self, input: &Constant<'a>) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ impl<'a, R: ExpressionVisitor<'a>> VisitorDirector<'a, R> {
|
||||
Expression::CircuitInit(e) => self.visit_circuit_init(e),
|
||||
Expression::Ternary(e) => self.visit_ternary_expression(e),
|
||||
Expression::Cast(e) => self.visit_cast_expression(e),
|
||||
Expression::SizeOf(e) => self.visit_sizeof_expression(e),
|
||||
Expression::Constant(e) => self.visit_constant(e),
|
||||
Expression::TupleAccess(e) => self.visit_tuple_access(e),
|
||||
Expression::TupleInit(e) => self.visit_tuple_init(e),
|
||||
@ -195,6 +196,16 @@ impl<'a, R: ExpressionVisitor<'a>> VisitorDirector<'a, R> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_sizeof_expression(&mut self, input: &SizeOfExpression<'a>) -> ConcreteVisitResult {
|
||||
match self.visitor.visit_sizeof_expression(input) {
|
||||
VisitResult::VisitChildren => {
|
||||
self.visit_expression(&input.inner)?;
|
||||
Ok(())
|
||||
}
|
||||
x => x.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_constant(&mut self, input: &Constant<'a>) -> ConcreteVisitResult {
|
||||
self.visitor.visit_constant(input).into()
|
||||
}
|
||||
|
@ -54,6 +54,8 @@ mod call;
|
||||
pub use call::*;
|
||||
mod cast;
|
||||
pub use cast::*;
|
||||
mod sizeof;
|
||||
pub use sizeof::*;
|
||||
|
||||
/// Expression that evaluates to a value
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
@ -64,6 +66,7 @@ pub enum Expression {
|
||||
Unary(UnaryExpression),
|
||||
Ternary(TernaryExpression),
|
||||
Cast(CastExpression),
|
||||
SizeOf(SizeOfExpression),
|
||||
|
||||
ArrayInline(ArrayInlineExpression),
|
||||
ArrayInit(ArrayInitExpression),
|
||||
@ -100,6 +103,7 @@ impl Node for Expression {
|
||||
CircuitStaticFunctionAccess(n) => n.span(),
|
||||
Call(n) => n.span(),
|
||||
Cast(n) => n.span(),
|
||||
SizeOf(n) => n.span(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,6 +126,7 @@ impl Node for Expression {
|
||||
CircuitStaticFunctionAccess(n) => n.set_span(span),
|
||||
Call(n) => n.set_span(span),
|
||||
Cast(n) => n.set_span(span),
|
||||
SizeOf(n) => n.set_span(span),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -146,6 +151,7 @@ impl fmt::Display for Expression {
|
||||
CircuitStaticFunctionAccess(n) => n.fmt(f),
|
||||
Call(n) => n.fmt(f),
|
||||
Cast(n) => n.fmt(f),
|
||||
SizeOf(n) => n.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
41
ast/src/expression/sizeof.rs
Normal file
41
ast/src/expression/sizeof.rs
Normal file
@ -0,0 +1,41 @@
|
||||
// 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 crate::Type;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct SizeOfExpression {
|
||||
pub inner: Box<Expression>,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for SizeOfExpression {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "sizeof {}", self.inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for SizeOfExpression {
|
||||
fn span(&self) -> &Span {
|
||||
&self.span
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
self.span = span;
|
||||
}
|
||||
}
|
@ -57,6 +57,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
Expression::Unary(unary) => Expression::Unary(self.reduce_unary(unary)?),
|
||||
Expression::Ternary(ternary) => Expression::Ternary(self.reduce_ternary(ternary)?),
|
||||
Expression::Cast(cast) => Expression::Cast(self.reduce_cast(cast)?),
|
||||
Expression::SizeOf(sizeof) => Expression::SizeOf(sizeof.clone()), // Expression::SizeOf(self.reduce_sizeof(sizeof)?), // TODO: add reducer
|
||||
|
||||
Expression::ArrayInline(array_inline) => Expression::ArrayInline(self.reduce_array_inline(array_inline)?),
|
||||
Expression::ArrayInit(array_init) => Expression::ArrayInit(self.reduce_array_init(array_init)?),
|
||||
|
@ -98,6 +98,9 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
// Cast
|
||||
Expression::Cast(_) => unimplemented!("casts not implemented"),
|
||||
|
||||
// SizeOf
|
||||
Expression::SizeOf(sizeof) => self.enforce_sizeof(cs, sizeof, span),
|
||||
|
||||
// Variables
|
||||
Expression::VariableRef(variable_ref) => self.evaluate_ref(variable_ref),
|
||||
|
||||
|
@ -43,6 +43,9 @@ pub use self::variable_ref::*;
|
||||
pub mod logical;
|
||||
pub use self::logical::*;
|
||||
|
||||
pub mod operator;
|
||||
pub use self::operator::*;
|
||||
|
||||
pub mod relational;
|
||||
pub use self::relational::*;
|
||||
|
||||
|
18
compiler/src/expression/operator/mod.rs
Normal file
18
compiler/src/expression/operator/mod.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// 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/>.
|
||||
|
||||
pub mod sizeof;
|
||||
pub use self::sizeof::*;
|
47
compiler/src/expression/operator/sizeof.rs
Normal file
47
compiler/src/expression/operator/sizeof.rs
Normal file
@ -0,0 +1,47 @@
|
||||
// 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/>.
|
||||
|
||||
//! Enforces a sizeof operator in a compiled Leo program.
|
||||
|
||||
use crate::{
|
||||
program::ConstrainedProgram,
|
||||
value::{ConstrainedValue, Integer},
|
||||
GroupType,
|
||||
};
|
||||
use leo_asg::{ConstInt, SizeOfExpression};
|
||||
use leo_errors::{Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
|
||||
impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
/// Enforce array expressions
|
||||
pub fn enforce_sizeof<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
sizeof: &'a SizeOfExpression<'a>,
|
||||
_span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let value = self.enforce_expression(cs, sizeof.inner.get())?;
|
||||
|
||||
Ok(match value {
|
||||
ConstrainedValue::Array(array) => {
|
||||
ConstrainedValue::Integer(Integer::new(&ConstInt::U32(array.len() as u32)))
|
||||
}
|
||||
_ => unimplemented!("sizeof can only be used for arrays"),
|
||||
})
|
||||
}
|
||||
}
|
@ -727,6 +727,10 @@ impl ParserContext {
|
||||
};
|
||||
Expression::Identifier(ident)
|
||||
}
|
||||
Token::SizeOf => Expression::SizeOf(SizeOfExpression {
|
||||
span,
|
||||
inner: Box::new(self.parse_primary_expression()?),
|
||||
}),
|
||||
token => {
|
||||
return Err(ParserError::unexpected_str(token, "expression", &span).into());
|
||||
}
|
||||
|
@ -519,6 +519,7 @@ impl Token {
|
||||
"string" => Token::String,
|
||||
"true" => Token::True,
|
||||
"type" => Token::Type,
|
||||
"sizeof" => Token::SizeOf,
|
||||
"u8" => Token::U8,
|
||||
"u16" => Token::U16,
|
||||
"u32" => Token::U32,
|
||||
|
@ -139,6 +139,10 @@ pub enum Token {
|
||||
Static,
|
||||
String,
|
||||
Type,
|
||||
|
||||
// Operators
|
||||
SizeOf,
|
||||
|
||||
// Not yet in ABNF
|
||||
// BitAnd,
|
||||
// BitAndEq,
|
||||
@ -195,6 +199,7 @@ pub const KEYWORD_TOKENS: &[Token] = &[
|
||||
Token::String,
|
||||
Token::True,
|
||||
Token::Type,
|
||||
Token::SizeOf,
|
||||
Token::U8,
|
||||
Token::U16,
|
||||
Token::U32,
|
||||
@ -307,6 +312,7 @@ impl fmt::Display for Token {
|
||||
Static => write!(f, "static"),
|
||||
String => write!(f, "string"),
|
||||
Type => write!(f, "type"),
|
||||
SizeOf => write!(f, "sizeof"),
|
||||
Eof => write!(f, ""),
|
||||
// BitAnd => write!(f, "&"),
|
||||
// BitAndEq => write!(f, "&="),
|
||||
|
Loading…
Reference in New Issue
Block a user