Merge pull request #1036 from AleoHQ/bug/1012-scalar-values

Scalar, Non-Scalar, and Char Output file
This commit is contained in:
Alessandro Coglio 2021-06-18 09:01:07 -07:00 committed by GitHub
commit 23e9622212
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 1037 additions and 478 deletions

View File

@ -102,6 +102,22 @@ impl From<leo_ast::GroupValue> for GroupValue {
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum CharValue {
Scalar(char),
NonScalar(u32),
}
impl From<leo_ast::CharValue> for CharValue {
fn from(other: leo_ast::CharValue) -> Self {
use leo_ast::Char::*;
match other.character {
Scalar(value) => CharValue::Scalar(value),
NonScalar(value) => CharValue::NonScalar(value),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum ConstValue {
Int(ConstInt),
@ -109,7 +125,7 @@ pub enum ConstValue {
Field(BigInt),
Address(StrTendril),
Boolean(bool),
Char(char),
Char(CharValue),
// compounds
Tuple(Vec<ConstValue>),

View File

@ -16,6 +16,7 @@
use crate::{
AsgConvertError,
CharValue,
ConstInt,
ConstValue,
Expression,
@ -118,22 +119,22 @@ impl<'a> FromAst<'a, leo_ast::ValueExpression> for Constant<'a> {
),
}
}
Char(value, span) => {
Char(value) => {
match expected_type.map(PartialType::full).flatten() {
Some(Type::Char) | None => (),
Some(x) => {
return Err(AsgConvertError::unexpected_type(
&x.to_string(),
Some(&*Type::Char.to_string()),
span,
value.span(),
));
}
}
Constant {
parent: Cell::new(None),
span: Some(span.clone()),
value: ConstValue::Char(*value),
span: Some(value.span().clone()),
value: ConstValue::Char(CharValue::from(value.clone())),
}
}
Field(value, span) => {
@ -236,7 +237,16 @@ impl<'a> Into<leo_ast::ValueExpression> for &Constant<'a> {
ConstValue::Boolean(value) => {
leo_ast::ValueExpression::Boolean(value.to_string().into(), self.span.clone().unwrap_or_default())
}
ConstValue::Char(value) => leo_ast::ValueExpression::Char(*value, self.span.clone().unwrap_or_default()),
ConstValue::Char(value) => match value {
CharValue::Scalar(scalar) => leo_ast::ValueExpression::Char(leo_ast::CharValue {
character: leo_ast::Char::Scalar(*scalar),
span: self.span.clone().unwrap_or_default(),
}),
CharValue::NonScalar(non_scalar) => leo_ast::ValueExpression::Char(leo_ast::CharValue {
character: leo_ast::Char::NonScalar(*non_scalar),
span: self.span.clone().unwrap_or_default(),
}),
},
ConstValue::Field(value) => {
leo_ast::ValueExpression::Field(value.to_string().into(), self.span.clone().unwrap_or_default())
}

View File

@ -0,0 +1,77 @@
// 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::common::span::Span;
use serde::{Deserialize, Serialize};
// use serde::de::{Deserialize as SerDeserialize, Deserializer};
use std::fmt;
fn char_to_u32<S>(character: &char, serializer: S) -> Result<S::Ok, S::Error>
where
S: ::serde::ser::Serializer,
{
serializer.serialize_u32(*character as u32)
}
fn char_from_u32<'de, D>(deserializer: D) -> Result<char, D::Error>
where
D: ::serde::de::Deserializer<'de>,
{
let int = u32::deserialize(deserializer)?;
std::char::from_u32(int).ok_or_else(|| ::serde::de::Error::custom("Failed to convert u32 to scalar char."))
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Char {
Scalar(
#[serde(deserialize_with = "char_from_u32")]
#[serde(serialize_with = "char_to_u32")]
char,
),
NonScalar(u32),
}
impl fmt::Display for Char {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Scalar(c) => write!(f, "{}", c),
Self::NonScalar(c) => write!(f, "{}", c),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CharValue {
pub character: Char,
pub span: Span,
}
impl fmt::Display for CharValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.character)
}
}
impl CharValue {
pub fn set_span(&mut self, new_span: Span) {
self.span = new_span;
}
pub fn span(&self) -> &Span {
&self.span
}
}

18
ast/src/chars/mod.rs Normal file
View 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 char_value;
pub use self::char_value::*;

View File

@ -35,12 +35,6 @@ impl ReducerError {
ReducerError::Error(FormattedError::new_from_span(message, span))
}
pub fn failed_to_convert_tendril_to_char(tendril: String, span: &Span) -> Self {
let message = format!("Failed to convert tendril `{}` to char", tendril);
Self::new_from_span(message, span)
}
pub fn impossible_console_assert_call(span: &Span) -> Self {
let message = "Console::Assert cannot be matched here, its handled in another case.".to_string();

View File

@ -17,14 +17,14 @@
use tendril::StrTendril;
use super::*;
use crate::GroupTuple;
use crate::{Char, CharValue, GroupTuple};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ValueExpression {
// todo: deserialize values here
Address(#[serde(with = "crate::common::tendril_json")] StrTendril, Span),
Boolean(#[serde(with = "crate::common::tendril_json")] StrTendril, Span),
Char(char, Span),
Char(CharValue),
Field(#[serde(with = "crate::common::tendril_json")] StrTendril, Span),
Group(Box<GroupValue>),
Implicit(#[serde(with = "crate::common::tendril_json")] StrTendril, Span),
@ -33,7 +33,7 @@ pub enum ValueExpression {
#[serde(with = "crate::common::tendril_json")] StrTendril,
Span,
),
String(String, Span),
String(Vec<Char>, Span),
}
impl fmt::Display for ValueExpression {
@ -42,12 +42,17 @@ impl fmt::Display for ValueExpression {
match &self {
Address(address, _) => write!(f, "{}", address),
Boolean(boolean, _) => write!(f, "{}", boolean),
Char(character, _) => write!(f, "{}", character),
Char(character) => write!(f, "{}", character),
Field(field, _) => write!(f, "{}", field),
Implicit(implicit, _) => write!(f, "{}", implicit),
Integer(value, type_, _) => write!(f, "{}{}", value, type_),
Group(group) => write!(f, "{}", group),
String(string, _) => write!(f, "{}", string),
String(string, _) => {
for character in string.iter() {
write!(f, "{}", character)?;
}
Ok(())
}
}
}
}
@ -58,11 +63,11 @@ impl Node for ValueExpression {
match &self {
Address(_, span)
| Boolean(_, span)
| Char(_, span)
| Field(_, span)
| Implicit(_, span)
| Integer(_, _, span)
| String(_, span) => span,
Char(character) => &character.span,
Group(group) => match &**group {
GroupValue::Single(_, span) | GroupValue::Tuple(GroupTuple { span, .. }) => span,
},
@ -74,11 +79,11 @@ impl Node for ValueExpression {
match self {
Address(_, span)
| Boolean(_, span)
| Char(_, span)
| Field(_, span)
| Implicit(_, span)
| Integer(_, _, span)
| String(_, span) => *span = new_span,
Char(character) => character.span = new_span,
Group(group) => match &mut **group {
GroupValue::Single(_, span) | GroupValue::Tuple(GroupTuple { span, .. }) => *span = new_span,
},

View File

@ -14,7 +14,7 @@
// 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::{ArrayDimensions, GroupValue};
use crate::{ArrayDimensions, Char, CharValue, GroupValue, Span as AstSpan};
use leo_input::{
errors::InputParserError,
expressions::{ArrayInitializerExpression, ArrayInlineExpression, Expression, StringExpression, TupleExpression},
@ -23,7 +23,7 @@ use leo_input::{
Address,
AddressValue,
BooleanValue,
CharValue,
CharValue as InputCharValue,
FieldValue,
GroupValue as InputGroupValue,
NumberValue,
@ -38,7 +38,7 @@ use std::fmt;
pub enum InputValue {
Address(String),
Boolean(bool),
Char(char),
Char(CharValue),
Field(String),
Group(GroupValue),
Integer(IntegerType, String),
@ -63,9 +63,14 @@ impl InputValue {
Ok(InputValue::Boolean(boolean))
}
fn from_char(character: CharValue) -> Result<Self, InputParserError> {
let character = character.value.inner()?;
Ok(InputValue::Char(character))
fn from_char(input_character: InputCharValue) -> Result<Self, InputParserError> {
let character = match input_character.value.inner()? {
leo_input::values::Char::Scalar(scalar) => Char::Scalar(scalar),
leo_input::values::Char::NonScalar(non_scalar) => Char::NonScalar(non_scalar),
};
let span = AstSpan::from(input_character.span);
Ok(InputValue::Char(CharValue { character, span }))
}
fn from_number(integer_type: IntegerType, number: String) -> Self {
@ -157,7 +162,7 @@ impl InputValue {
for character in string.chars.into_iter() {
let element = InputValue::from_expression(
inner_array_type.clone(),
Expression::Value(Value::Char(CharValue {
Expression::Value(Value::Char(InputCharValue {
value: character.clone(),
span: character.span().clone(),
})),

View File

@ -29,6 +29,9 @@ pub use self::annotation::*;
pub mod circuits;
pub use self::circuits::*;
pub mod chars;
pub use self::chars::*;
pub mod common;
pub use self::common::*;

View File

@ -485,11 +485,48 @@ impl ReconstructingReducer for Canonicalizer {
}
}
fn reduce_string(&mut self, string: &str, span: &Span) -> Result<Expression, ReducerError> {
fn reduce_string(&mut self, string: &[Char], span: &Span) -> Result<Expression, ReducerError> {
let mut elements = Vec::new();
for character in string.chars() {
let mut col_adder = 0;
for (index, character) in string.iter().enumerate() {
let col_start = span.col_start + index + 1 + col_adder; // account for open quote
let bytes = span.content.clone().into_bytes();
let col_stop: usize;
if bytes[col_start - 1] == b'\\' {
let mut width = 0;
match bytes[col_start] {
b'x' => width += 3,
b'u' => {
width += 1;
let mut index = 1;
while bytes[col_start + index] != b'}' {
width += 1;
index += 1;
}
width += 1;
}
_ => width += 1,
}
col_adder += width;
col_stop = col_start + 1 + width;
} else {
col_stop = col_start + 1;
}
elements.push(SpreadOrExpression::Expression(Expression::Value(
ValueExpression::Char(character, span.clone()),
ValueExpression::Char(CharValue {
character: character.clone(),
span: Span {
line_start: span.line_start,
line_stop: span.line_stop,
col_start,
col_stop,
path: span.path.clone(),
content: span.content.clone(),
},
}),
)));
}

View File

@ -100,7 +100,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
self.reducer.reduce_group_value(group_value, new)
}
pub fn reduce_string(&mut self, string: &str, span: &Span) -> Result<Expression, ReducerError> {
pub fn reduce_string(&mut self, string: &[Char], span: &Span) -> Result<Expression, ReducerError> {
self.reducer.reduce_string(string, span)
}

View File

@ -51,9 +51,9 @@ pub trait ReconstructingReducer {
Ok(new)
}
fn reduce_string(&mut self, string: &str, span: &Span) -> Result<Expression, ReducerError> {
fn reduce_string(&mut self, string: &[Char], span: &Span) -> Result<Expression, ReducerError> {
Ok(Expression::Value(ValueExpression::String(
string.to_string(),
string.to_vec(),
span.clone(),
)))
}

View File

@ -14,7 +14,7 @@
// 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::{Expression, Node, Span};
use crate::{Char, Expression, Node, Span};
use serde::{Deserialize, Serialize};
use std::fmt;
@ -27,28 +27,38 @@ pub enum FormatStringPart {
}
impl FormatStringPart {
pub fn from_string(string: String) -> Vec<Self> {
pub fn from_string(string: Vec<Char>) -> Vec<Self> {
let mut parts = Vec::new();
let mut in_container = false;
let mut start = 0;
for (index, character) in string.chars().enumerate() {
let mut substring = String::new();
for (_, character) in string.iter().enumerate() {
match character {
'{' if !in_container => {
parts.push(FormatStringPart::Const(string[start..index].into()));
start = index;
in_container = true;
}
'}' if in_container => {
in_container = false;
parts.push(FormatStringPart::Container);
}
_ if in_container => {
Char::Scalar(scalar) => match scalar {
'{' if !in_container => {
parts.push(FormatStringPart::Const(substring.clone().into()));
substring.clear();
in_container = true;
}
'}' if in_container => {
in_container = false;
parts.push(FormatStringPart::Container);
}
_ if in_container => {
in_container = false;
}
_ => substring.push(*scalar),
},
Char::NonScalar(non_scalar) => {
substring.push_str(format!("\\u{{{:x}}}", non_scalar).as_str());
in_container = false;
}
_ => {}
}
}
if !substring.is_empty() {
parts.push(FormatStringPart::Const(substring.into()));
}
parts
}
}

View File

@ -23,7 +23,7 @@ use crate::{
program::ConstrainedProgram,
relational::*,
resolve_core_circuit,
value::{Address, Char, ConstrainedValue, Integer},
value::{Address, Char, CharType, ConstrainedValue, Integer},
FieldType,
GroupType,
};
@ -44,7 +44,21 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
ConstValue::Address(value) => ConstrainedValue::Address(Address::constant(value.to_string(), span)?),
ConstValue::Boolean(value) => ConstrainedValue::Boolean(Boolean::Constant(*value)),
ConstValue::Char(value) => {
ConstrainedValue::Char(Char::constant(cs, *value, format!("{}", *value as u32), span)?)
use leo_asg::CharValue::*;
match value {
Scalar(scalar) => ConstrainedValue::Char(Char::constant(
cs,
CharType::Scalar(*scalar),
format!("{}", *scalar as u32),
span,
)?),
NonScalar(non_scalar) => ConstrainedValue::Char(Char::constant(
cs,
CharType::NonScalar(*non_scalar),
format!("{}", *non_scalar),
span,
)?),
}
}
ConstValue::Field(value) => ConstrainedValue::Field(FieldType::constant(cs, value.to_string(), span)?),
ConstValue::Group(value) => ConstrainedValue::Group(G::constant(value, span)?),

View File

@ -27,13 +27,13 @@ use crate::{
group::input::group_from_input,
ConstrainedValue,
},
Char,
CharType,
FieldType,
GroupType,
Integer,
};
use leo_asg::{ConstInt, Type};
use leo_ast::{InputValue, Span};
use leo_ast::{Char, InputValue, Span};
use snarkvm_fields::PrimeField;
use snarkvm_gadgets::boolean::Boolean;
@ -83,12 +83,20 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
match (type_, input) {
(Type::Address, InputValue::Address(addr)) => Ok(ConstrainedValue::Address(Address::constant(addr, span)?)),
(Type::Boolean, InputValue::Boolean(value)) => Ok(ConstrainedValue::Boolean(Boolean::constant(value))),
(Type::Char, InputValue::Char(character)) => Ok(ConstrainedValue::Char(Char::constant(
cs,
character,
format!("{}", character as u32),
span,
)?)),
(Type::Char, InputValue::Char(character)) => match character.character {
Char::Scalar(scalar) => Ok(ConstrainedValue::Char(crate::Char::constant(
cs,
CharType::Scalar(scalar),
format!("{}", scalar as u32),
span,
)?)),
Char::NonScalar(non_scalar) => Ok(ConstrainedValue::Char(crate::Char::constant(
cs,
CharType::NonScalar(non_scalar),
format!("{}", non_scalar),
span,
)?)),
},
(Type::Field, InputValue::Field(value)) => {
Ok(ConstrainedValue::Field(FieldType::constant(cs, value, span)?))
}

View File

@ -22,7 +22,7 @@ pub use self::output_file::*;
pub mod output_bytes;
pub use self::output_bytes::*;
use crate::{errors::OutputBytesError, ConstrainedValue, GroupType, REGISTERS_VARIABLE_NAME};
use crate::{errors::OutputBytesError, Char, CharType, ConstrainedValue, GroupType, REGISTERS_VARIABLE_NAME};
use leo_asg::Program;
use leo_ast::{Parameter, Registers, Span};
@ -47,10 +47,7 @@ impl fmt::Display for Output {
writeln!(f, "[{}]", REGISTERS_VARIABLE_NAME)?;
// format: "token_id: u64 = 1u64;"
for (name, register) in self.registers.iter() {
match register.type_.as_str() {
"char" => writeln!(f, "{}: {} = '{}';", name, register.type_, register.value)?,
_ => writeln!(f, "{}: {} = {};", name, register.type_, register.value)?,
}
writeln!(f, "{}: {} = {};", name, register.type_, register.value)?;
}
Ok(())
}
@ -63,6 +60,28 @@ impl Into<OutputBytes> for Output {
}
}
fn char_to_output_string<F: PrimeField>(character: &Char<F>, quote: bool) -> String {
let mut string = String::new();
if quote {
string.push('\'');
}
match character.character {
CharType::Scalar(scalar) => {
if scalar.is_alphanumeric() {
string.push(scalar);
} else {
string.push_str(format!("{}", char::escape_default(scalar)).as_str());
}
}
CharType::NonScalar(non_scalar) => string.push_str(format!("\\u{{{:x}}}", non_scalar).as_str()),
}
if quote {
string.push('\'');
}
string
}
impl Output {
pub fn new<'a, F: PrimeField, G: GroupType<F>>(
program: &Program<'a>,
@ -71,7 +90,7 @@ impl Output {
span: &Span,
) -> Result<Self, OutputBytesError> {
let return_values = match value {
ConstrainedValue::Tuple(values) => values,
ConstrainedValue::Tuple(tuple) => tuple,
value => vec![value],
};
let register_hashmap = registers.values();
@ -106,7 +125,38 @@ impl Output {
));
}
let value = value.to_string();
let value = match value {
ConstrainedValue::Char(c) => char_to_output_string(&c, true),
ConstrainedValue::Array(array) => {
let mut string = String::new();
string.push('"');
for e in array.iter() {
if let ConstrainedValue::Char(c) = e {
string.push_str(char_to_output_string(c, false).as_str());
} else {
string.push_str(e.to_string().as_str());
}
}
string.push('"');
string
}
ConstrainedValue::Tuple(tuple) => {
let values = tuple
.iter()
.map(|e| {
if let ConstrainedValue::Char(c) = e {
char_to_output_string(c, true)
} else {
e.to_string()
}
})
.collect::<Vec<_>>()
.join(", ");
format!("({})", values)
}
_ => value.to_string(),
};
registers.insert(name.to_string(), OutputRegister {
type_: register_type.to_string(),

View File

@ -28,6 +28,7 @@ use leo_asg::{
BlockStatement as AsgBlockStatement,
CallExpression as AsgCallExpression,
CastExpression as AsgCastExpression,
CharValue as AsgCharValue,
Circuit as AsgCircuit,
CircuitAccessExpression as AsgCircuitAccessExpression,
CircuitInitExpression as AsgCircuitInitExpression,
@ -65,6 +66,8 @@ use leo_ast::{
Block as AstBlockStatement,
CallExpression as AstCallExpression,
CastExpression as AstCastExpression,
Char,
CharValue as AstCharValue,
Circuit as AstCircuit,
CircuitImpliedVariableDefinition,
CircuitInitExpression as AstCircuitInitExpression,
@ -431,14 +434,16 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
ConstValue::Boolean(_) => {
new = ValueExpression::Boolean(tendril.clone(), span.clone());
}
ConstValue::Char(_) => {
if let Some(c) = tendril.chars().next() {
new = ValueExpression::Char(c, span.clone());
} else {
return Err(ReducerError::failed_to_convert_tendril_to_char(
tendril.to_string(),
span,
));
ConstValue::Char(asg_char) => {
new = match asg_char {
AsgCharValue::Scalar(scalar) => ValueExpression::Char(AstCharValue {
character: Char::Scalar(*scalar),
span: span.clone(),
}),
AsgCharValue::NonScalar(non_scalar) => ValueExpression::Char(AstCharValue {
character: Char::NonScalar(*non_scalar),
span: span.clone(),
}),
}
}
_ => unimplemented!(), // impossible?

View File

@ -31,17 +31,23 @@ use snarkvm_gadgets::{
};
use snarkvm_r1cs::{ConstraintSystem, SynthesisError};
#[derive(Clone, Debug)]
pub enum CharType {
Scalar(char),
NonScalar(u32),
}
/// A char
#[derive(Clone, Debug)]
pub struct Char<F: PrimeField> {
pub character: char,
pub character: CharType,
pub field: FieldType<F>,
}
impl<F: PrimeField> Char<F> {
pub fn constant<CS: ConstraintSystem<F>>(
cs: CS,
character: char,
character: CharType,
field: String,
span: &Span,
) -> Result<Self, CharError> {
@ -118,13 +124,13 @@ impl<F: PrimeField> CondSelectGadget<F> for Char<F> {
if field == first.field {
return Ok(Char {
character: first.character,
character: first.character.clone(),
field,
});
}
Ok(Char {
character: second.character,
character: second.character.clone(),
field,
})
}
@ -144,12 +150,17 @@ pub(crate) fn char_from_input<'a, F: PrimeField, G: GroupType<F>, CS: Constraint
let option = match input_value {
Some(input) => {
if let InputValue::Char(character) = input {
(character, Some((character as u32).to_string()))
match character.character {
leo_ast::Char::Scalar(scalar) => (CharType::Scalar(scalar), Some((scalar as u32).to_string())),
leo_ast::Char::NonScalar(non_scalar) => {
(CharType::NonScalar(non_scalar), Some(non_scalar.to_string()))
}
}
} else {
return Err(CharError::invalid_char(input.to_string(), span));
}
}
None => (' ', None),
None => (CharType::Scalar(0 as char), None),
};
let field = allocate_field(cs, name, option.1, span)?;
@ -162,6 +173,9 @@ pub(crate) fn char_from_input<'a, F: PrimeField, G: GroupType<F>, CS: Constraint
impl<F: PrimeField + std::fmt::Display> std::fmt::Display for Char<F> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", char::escape_default(self.character))
match self.character {
CharType::Scalar(scalar) => write!(f, "{}", scalar),
CharType::NonScalar(non_scalar) => write!(f, "\\u{{{:X}}}", non_scalar),
}
}
}

View File

@ -20,239 +20,293 @@
"variable_names": [
{
"mutable": true,
"identifier": "{\"name\":\"s\",\"span\":\"{\\\"line_start\\\":2,\\\"line_stop\\\":2,\\\"col_start\\\":9,\\\"col_stop\\\":10,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let s = \\\\\\\"\\\\\\\\u{2764}ello, World!\\\\\\\";\\\"}\"}",
"identifier": "{\"name\":\"s\",\"span\":\"{\\\"line_start\\\":2,\\\"line_stop\\\":2,\\\"col_start\\\":9,\\\"col_stop\\\":10,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let s = \\\\\\\"\\\\\\\\u{2764}ello, World!\\\\\\\\u{DDDD}\\\\\\\";\\\"}\"}",
"span": {
"line_start": 2,
"line_stop": 2,
"col_start": 9,
"col_stop": 10,
"path": "",
"content": " let s = \"\\u{2764}ello, World!\";"
"content": " let s = \"\\u{2764}ello, World!\\u{DDDD}\";"
}
}
],
"type_": null,
"type_": {
"Array": [
"Char",
[
{
"value": "14"
}
]
]
},
"value": {
"ArrayInline": {
"elements": [
{
"Expression": {
"Value": {
"Char": [
"❤",
{
"Char": {
"character": {
"Scalar": 10084
},
"span": {
"line_start": 2,
"line_stop": 2,
"col_start": 13,
"col_stop": 35,
"col_start": 14,
"col_stop": 22,
"path": "",
"content": " let s = \"\\u{2764}ello, World!\";"
"content": " let s = \"\\u{2764}ello, World!\\u{DDDD}\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"e",
{
"Char": {
"character": {
"Scalar": 101
},
"span": {
"line_start": 2,
"line_stop": 2,
"col_start": 13,
"col_stop": 35,
"col_start": 22,
"col_stop": 23,
"path": "",
"content": " let s = \"\\u{2764}ello, World!\";"
"content": " let s = \"\\u{2764}ello, World!\\u{DDDD}\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"l",
{
"Char": {
"character": {
"Scalar": 108
},
"span": {
"line_start": 2,
"line_stop": 2,
"col_start": 13,
"col_stop": 35,
"col_start": 23,
"col_stop": 24,
"path": "",
"content": " let s = \"\\u{2764}ello, World!\";"
"content": " let s = \"\\u{2764}ello, World!\\u{DDDD}\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"l",
{
"Char": {
"character": {
"Scalar": 108
},
"span": {
"line_start": 2,
"line_stop": 2,
"col_start": 13,
"col_stop": 35,
"col_start": 24,
"col_stop": 25,
"path": "",
"content": " let s = \"\\u{2764}ello, World!\";"
"content": " let s = \"\\u{2764}ello, World!\\u{DDDD}\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"o",
{
"Char": {
"character": {
"Scalar": 111
},
"span": {
"line_start": 2,
"line_stop": 2,
"col_start": 13,
"col_stop": 35,
"col_start": 25,
"col_stop": 26,
"path": "",
"content": " let s = \"\\u{2764}ello, World!\";"
"content": " let s = \"\\u{2764}ello, World!\\u{DDDD}\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
",",
{
"Char": {
"character": {
"Scalar": 44
},
"span": {
"line_start": 2,
"line_stop": 2,
"col_start": 13,
"col_stop": 35,
"col_start": 26,
"col_stop": 27,
"path": "",
"content": " let s = \"\\u{2764}ello, World!\";"
"content": " let s = \"\\u{2764}ello, World!\\u{DDDD}\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
" ",
{
"Char": {
"character": {
"Scalar": 32
},
"span": {
"line_start": 2,
"line_stop": 2,
"col_start": 13,
"col_stop": 35,
"col_start": 27,
"col_stop": 28,
"path": "",
"content": " let s = \"\\u{2764}ello, World!\";"
"content": " let s = \"\\u{2764}ello, World!\\u{DDDD}\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"W",
{
"Char": {
"character": {
"Scalar": 87
},
"span": {
"line_start": 2,
"line_stop": 2,
"col_start": 13,
"col_stop": 35,
"col_start": 28,
"col_stop": 29,
"path": "",
"content": " let s = \"\\u{2764}ello, World!\";"
"content": " let s = \"\\u{2764}ello, World!\\u{DDDD}\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"o",
{
"Char": {
"character": {
"Scalar": 111
},
"span": {
"line_start": 2,
"line_stop": 2,
"col_start": 13,
"col_stop": 35,
"col_start": 29,
"col_stop": 30,
"path": "",
"content": " let s = \"\\u{2764}ello, World!\";"
"content": " let s = \"\\u{2764}ello, World!\\u{DDDD}\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"r",
{
"Char": {
"character": {
"Scalar": 114
},
"span": {
"line_start": 2,
"line_stop": 2,
"col_start": 13,
"col_stop": 35,
"col_start": 30,
"col_stop": 31,
"path": "",
"content": " let s = \"\\u{2764}ello, World!\";"
"content": " let s = \"\\u{2764}ello, World!\\u{DDDD}\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"l",
{
"Char": {
"character": {
"Scalar": 108
},
"span": {
"line_start": 2,
"line_stop": 2,
"col_start": 13,
"col_stop": 35,
"col_start": 31,
"col_stop": 32,
"path": "",
"content": " let s = \"\\u{2764}ello, World!\";"
"content": " let s = \"\\u{2764}ello, World!\\u{DDDD}\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"d",
{
"Char": {
"character": {
"Scalar": 100
},
"span": {
"line_start": 2,
"line_stop": 2,
"col_start": 13,
"col_stop": 35,
"col_start": 32,
"col_stop": 33,
"path": "",
"content": " let s = \"\\u{2764}ello, World!\";"
"content": " let s = \"\\u{2764}ello, World!\\u{DDDD}\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"!",
{
"Char": {
"character": {
"Scalar": 33
},
"span": {
"line_start": 2,
"line_stop": 2,
"col_start": 13,
"col_stop": 35,
"col_start": 33,
"col_stop": 34,
"path": "",
"content": " let s = \"\\u{2764}ello, World!\";"
"content": " let s = \"\\u{2764}ello, World!\\u{DDDD}\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": {
"character": {
"NonScalar": 56797
},
"span": {
"line_start": 2,
"line_stop": 2,
"col_start": 34,
"col_stop": 42,
"path": "",
"content": " let s = \"\\u{2764}ello, World!\\u{DDDD}\";"
}
}
}
}
}
@ -261,9 +315,9 @@
"line_start": 2,
"line_stop": 2,
"col_start": 13,
"col_stop": 35,
"col_stop": 43,
"path": "",
"content": " let s = \"\\u{2764}ello, World!\";"
"content": " let s = \"\\u{2764}ello, World!\\u{DDDD}\";"
}
}
},
@ -271,9 +325,9 @@
"line_start": 2,
"line_stop": 2,
"col_start": 5,
"col_stop": 35,
"col_stop": 43,
"path": "",
"content": " let s = \"\\u{2764}ello, World!\";"
"content": " let s = \"\\u{2764}ello, World!\\u{DDDD}\";"
}
}
},
@ -288,7 +342,8 @@
null,
{
"Value": {
"Implicit": [
"Integer": [
"U32",
"2",
{
"line_start": 3,
@ -319,34 +374,38 @@
{
"Expression": {
"Value": {
"Char": [
"h",
{
"Char": {
"character": {
"Scalar": 104
},
"span": {
"line_start": 3,
"line_stop": 3,
"col_start": 14,
"col_stop": 18,
"col_start": 15,
"col_stop": 16,
"path": "",
"content": " s[..2] = \"he\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"e",
{
"Char": {
"character": {
"Scalar": 101
},
"span": {
"line_start": 3,
"line_stop": 3,
"col_start": 14,
"col_stop": 18,
"col_start": 16,
"col_stop": 17,
"path": "",
"content": " s[..2] = \"he\";"
}
]
}
}
}
}

View File

@ -1,4 +1,4 @@
function main() {
let s = "\u{2764}ello, World!";
let s = "\u{2764}ello, World!\u{DDDD}";
s[..2] = "he";
}

View File

@ -1005,9 +1005,11 @@
"type_": "Char",
"value": {
"Value": {
"Char": [
"a",
{
"Char": {
"character": {
"Scalar": 97
},
"span": {
"line_start": 23,
"line_stop": 23,
"col_start": 13,
@ -1015,7 +1017,7 @@
"path": "",
"content": " const n = 'a';"
}
]
}
}
},
"span": {
@ -1061,221 +1063,247 @@
{
"Expression": {
"Value": {
"Char": [
"H",
{
"Char": {
"character": {
"Scalar": 72
},
"span": {
"line_start": 24,
"line_stop": 24,
"col_start": 13,
"col_stop": 28,
"col_start": 14,
"col_stop": 15,
"path": "",
"content": " const o = \"Hello, World!\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"e",
{
"Char": {
"character": {
"Scalar": 101
},
"span": {
"line_start": 24,
"line_stop": 24,
"col_start": 13,
"col_stop": 28,
"col_start": 15,
"col_stop": 16,
"path": "",
"content": " const o = \"Hello, World!\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"l",
{
"Char": {
"character": {
"Scalar": 108
},
"span": {
"line_start": 24,
"line_stop": 24,
"col_start": 13,
"col_stop": 28,
"col_start": 16,
"col_stop": 17,
"path": "",
"content": " const o = \"Hello, World!\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"l",
{
"Char": {
"character": {
"Scalar": 108
},
"span": {
"line_start": 24,
"line_stop": 24,
"col_start": 13,
"col_stop": 28,
"col_start": 17,
"col_stop": 18,
"path": "",
"content": " const o = \"Hello, World!\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"o",
{
"Char": {
"character": {
"Scalar": 111
},
"span": {
"line_start": 24,
"line_stop": 24,
"col_start": 13,
"col_stop": 28,
"col_start": 18,
"col_stop": 19,
"path": "",
"content": " const o = \"Hello, World!\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
",",
{
"Char": {
"character": {
"Scalar": 44
},
"span": {
"line_start": 24,
"line_stop": 24,
"col_start": 13,
"col_stop": 28,
"col_start": 19,
"col_stop": 20,
"path": "",
"content": " const o = \"Hello, World!\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
" ",
{
"Char": {
"character": {
"Scalar": 32
},
"span": {
"line_start": 24,
"line_stop": 24,
"col_start": 13,
"col_stop": 28,
"col_start": 20,
"col_stop": 21,
"path": "",
"content": " const o = \"Hello, World!\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"W",
{
"Char": {
"character": {
"Scalar": 87
},
"span": {
"line_start": 24,
"line_stop": 24,
"col_start": 13,
"col_stop": 28,
"col_start": 21,
"col_stop": 22,
"path": "",
"content": " const o = \"Hello, World!\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"o",
{
"Char": {
"character": {
"Scalar": 111
},
"span": {
"line_start": 24,
"line_stop": 24,
"col_start": 13,
"col_stop": 28,
"col_start": 22,
"col_stop": 23,
"path": "",
"content": " const o = \"Hello, World!\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"r",
{
"Char": {
"character": {
"Scalar": 114
},
"span": {
"line_start": 24,
"line_stop": 24,
"col_start": 13,
"col_stop": 28,
"col_start": 23,
"col_stop": 24,
"path": "",
"content": " const o = \"Hello, World!\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"l",
{
"Char": {
"character": {
"Scalar": 108
},
"span": {
"line_start": 24,
"line_stop": 24,
"col_start": 13,
"col_stop": 28,
"col_start": 24,
"col_stop": 25,
"path": "",
"content": " const o = \"Hello, World!\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"d",
{
"Char": {
"character": {
"Scalar": 100
},
"span": {
"line_start": 24,
"line_stop": 24,
"col_start": 13,
"col_stop": 28,
"col_start": 25,
"col_stop": 26,
"path": "",
"content": " const o = \"Hello, World!\";"
}
]
}
}
}
},
{
"Expression": {
"Value": {
"Char": [
"!",
{
"Char": {
"character": {
"Scalar": 33
},
"span": {
"line_start": 24,
"line_stop": 24,
"col_start": 13,
"col_stop": 28,
"col_start": 26,
"col_stop": 27,
"path": "",
"content": " const o = \"Hello, World!\";"
}
]
}
}
}
}

View File

@ -78,12 +78,18 @@ impl<'ast> CharTypes<'ast> {
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Char {
Scalar(char),
NonScalar(u32),
}
impl<'ast> CharTypes<'ast> {
pub fn inner(self) -> Result<char, InputParserError> {
pub fn inner(self) -> Result<Char, InputParserError> {
match self {
Self::Basic(character) => {
if let Some(character) = character.value.chars().next() {
return Ok(character);
return Ok(Char::Scalar(character));
}
Err(InputParserError::invalid_char(character.value, &character.span))
@ -91,13 +97,13 @@ impl<'ast> CharTypes<'ast> {
Self::Escaped(character) => {
if let Some(inner) = character.value.chars().nth(1) {
return match inner {
'0' => Ok(0 as char),
't' => Ok(9 as char),
'n' => Ok(10 as char),
'r' => Ok(13 as char),
'\"' => Ok(34 as char),
'\'' => Ok(39 as char),
'\\' => Ok(92 as char),
'0' => Ok(Char::Scalar(0 as char)),
't' => Ok(Char::Scalar(9 as char)),
'n' => Ok(Char::Scalar(10 as char)),
'r' => Ok(Char::Scalar(13 as char)),
'\"' => Ok(Char::Scalar(34 as char)),
'\'' => Ok(Char::Scalar(39 as char)),
'\\' => Ok(Char::Scalar(92 as char)),
_ => Err(InputParserError::invalid_char(character.value, &character.span)),
};
}
@ -108,7 +114,7 @@ impl<'ast> CharTypes<'ast> {
let hex_string_number = character.value[2..character.value.len()].to_string();
if let Ok(number) = u8::from_str_radix(&hex_string_number, 16) {
if number <= 127 {
return Ok(number as char);
return Ok(Char::Scalar(number as char));
}
}
@ -118,7 +124,9 @@ impl<'ast> CharTypes<'ast> {
let unicode_string_number = character.value[3..=character.value.len() - 2].to_string();
if let Ok(hex) = u32::from_str_radix(&unicode_string_number, 16) {
if let Some(unicode) = std::char::from_u32(hex) {
return Ok(unicode);
return Ok(Char::Scalar(unicode));
} else if hex <= 0x10FFFF {
return Ok(Char::NonScalar(hex));
}
}

View File

@ -689,7 +689,10 @@ impl ParserContext {
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::CharLit(value) => Expression::Value(ValueExpression::Char(value, span)),
Token::CharLit(value) => Expression::Value(ValueExpression::Char(CharValue {
character: value.into(),
span,
})),
Token::StringLit(value) => Expression::Value(ValueExpression::String(value, span)),
Token::LeftParen => self.parse_tuple_expression(&span)?,
Token::LeftSquare => self.parse_array_expression(&span)?,

View File

@ -14,7 +14,7 @@
// 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::tokenizer::Token;
use crate::tokenizer::{Char, Token};
use leo_ast::Span;
use serde::{Deserialize, Serialize};
use tendril::StrTendril;
@ -64,7 +64,7 @@ impl Token {
///
/// Returns a `char` if an character can be eaten, otherwise returns [`None`].
///
fn eat_char(input_tendril: StrTendril, escaped: bool, hex: bool, unicode: bool) -> Option<char> {
fn eat_char(input_tendril: StrTendril, escaped: bool, hex: bool, unicode: bool) -> Option<Char> {
if input_tendril.is_empty() {
return None;
}
@ -79,13 +79,13 @@ impl Token {
if let Some(character) = escaped.chars().next() {
return match character {
'0' => Some(0 as char),
't' => Some(9 as char),
'n' => Some(10 as char),
'r' => Some(13 as char),
'\"' => Some(34 as char),
'\'' => Some(39 as char),
'\\' => Some(92 as char),
'0' => Some(Char::Scalar(0 as char)),
't' => Some(Char::Scalar(9 as char)),
'n' => Some(Char::Scalar(10 as char)),
'r' => Some(Char::Scalar(13 as char)),
'\"' => Some(Char::Scalar(34 as char)),
'\'' => Some(Char::Scalar(39 as char)),
'\\' => Some(Char::Scalar(92 as char)),
_ => None,
};
} else {
@ -107,7 +107,7 @@ impl Token {
return None;
}
return Some(ascii_number as char);
return Some(Char::Scalar(ascii_number as char));
}
}
@ -125,7 +125,10 @@ impl Token {
if let Ok(hex) = u32::from_str_radix(&unicode_number, 16) {
if let Some(character) = std::char::from_u32(hex) {
return Some(character);
// scalar
return Some(Char::Scalar(character));
} else if hex <= 0x10FFFF {
return Some(Char::NonScalar(hex));
}
}
}
@ -133,7 +136,7 @@ impl Token {
if input_tendril.to_string().chars().count() != 1 {
return None;
} else if let Some(character) = input_tendril.to_string().chars().next() {
return Some(character);
return Some(Char::Scalar(character));
}
None
@ -209,7 +212,7 @@ impl Token {
let mut hex = false;
let mut unicode = false;
let mut end = false;
let mut string = String::new();
let mut string = Vec::new();
while i < input.len() {
// If it's an emoji get the length.
@ -264,7 +267,7 @@ impl Token {
escaped = false;
hex = false;
unicode = false;
string.push(character);
string.push(character.into());
}
None => return (0, None),
}

View File

@ -18,6 +18,31 @@ use serde::{Deserialize, Serialize};
use std::fmt;
use tendril::StrTendril;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum Char {
Scalar(char),
NonScalar(u32),
}
#[allow(clippy::from_over_into)]
impl Into<leo_ast::Char> for Char {
fn into(self) -> leo_ast::Char {
match self {
Self::Scalar(c) => leo_ast::Char::Scalar(c),
Self::NonScalar(c) => leo_ast::Char::NonScalar(c),
}
}
}
impl fmt::Display for Char {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Scalar(c) => write!(f, "{}", c),
Self::NonScalar(c) => write!(f, "{}", c),
}
}
}
/// Represents all valid Leo syntax tokens.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum Token {
@ -25,13 +50,13 @@ pub enum Token {
// Literals
CommentLine(#[serde(with = "leo_ast::common::tendril_json")] StrTendril),
CommentBlock(#[serde(with = "leo_ast::common::tendril_json")] StrTendril),
StringLit(String),
StringLit(Vec<leo_ast::Char>),
Ident(#[serde(with = "leo_ast::common::tendril_json")] StrTendril),
Int(#[serde(with = "leo_ast::common::tendril_json")] StrTendril),
True,
False,
AddressLit(#[serde(with = "leo_ast::common::tendril_json")] StrTendril),
CharLit(char),
CharLit(Char),
At,
@ -191,7 +216,13 @@ impl fmt::Display for Token {
match self {
CommentLine(s) => write!(f, "{}", s),
CommentBlock(s) => write!(f, "{}", s),
StringLit(content) => write!(f, "\"{}\"", content),
StringLit(string) => {
write!(f, "\"")?;
for character in string.iter() {
write!(f, "{}", character)?;
}
write!(f, "\"")
}
Ident(s) => write!(f, "{}", s),
Int(s) => write!(f, "{}", s),
True => write!(f, "true"),

View File

@ -15,10 +15,10 @@ outputs:
registers:
r:
type: "[u8; 3]"
value: "[3, 2, 1]"
value: "\"321\""
- input_file: input/registers_zeros.in
output:
registers:
r:
type: "[u8; 3]"
value: "[1, 2, 3]"
value: "\"123\""

View File

@ -15,88 +15,88 @@ outputs:
registers:
r:
type: char
value: a
value: "'a'"
- input_file: inputs/escaped_unicode1.in
output:
registers:
r:
type: char
value: "\\u{f}"
value: "'\\u{f}'"
- input_file: inputs/escaped_unicode2.in
output:
registers:
r:
type: char
value: "\\u{e5}"
value: "'å'"
- input_file: inputs/escaped_unicode3.in
output:
registers:
r:
type: char
value: "\\u{4e0}"
value: "'Ӡ'"
- input_file: inputs/escaped_unicode4.in
output:
registers:
r:
type: char
value: "\\u{2764}"
value: "'\\u{2764}'"
- input_file: inputs/escaped_unicode5.in
output:
registers:
r:
type: char
value: "\\u{1f622}"
value: "'\\u{1f622}'"
- input_file: inputs/escaped_unicode6.in
output:
registers:
r:
type: char
value: "\\u{10001f}"
value: "'\\u{10001f}'"
- input_file: inputs/escaped.in
output:
registers:
r:
type: char
value: "\\'"
value: "'\\''"
- input_file: inputs/hex1.in
output:
registers:
r:
type: char
value: "*"
value: "'*'"
- input_file: inputs/hex2.in
output:
registers:
r:
type: char
value: "\\u{7f}"
value: "'\\u{7f}'"
- input_file: inputs/unicode1.in
output:
registers:
r:
type: char
value: "\\u{e00f}"
value: "'\\u{e00f}'"
- input_file: inputs/unicode2.in
output:
registers:
r:
type: char
value: "\\u{e5}"
value: "'å'"
- input_file: inputs/unicode3.in
output:
registers:
r:
type: char
value: "\\u{4e0}"
value: "'Ӡ'"
- input_file: inputs/unicode4.in
output:
registers:
r:
type: char
value: "\\u{2764}"
value: "'\\u{2764}'"
- input_file: inputs/unicode5.in
output:
registers:
r:
type: char
value: "\\u{1f62d}"
value: "'\\u{1f62d}'"

View File

@ -15,88 +15,88 @@ outputs:
registers:
r:
type: char
value: Z
value: "'Z'"
- input_file: inputs/escaped_unicode1.in
output:
registers:
r:
type: char
value: a
value: "'a'"
- input_file: inputs/escaped_unicode2.in
output:
registers:
r:
type: char
value: a
value: "'a'"
- input_file: inputs/escaped_unicode3.in
output:
registers:
r:
type: char
value: a
value: "'a'"
- input_file: inputs/escaped_unicode4.in
output:
registers:
r:
type: char
value: a
value: "'a'"
- input_file: inputs/escaped_unicode5.in
output:
registers:
r:
type: char
value: a
value: "'a'"
- input_file: inputs/escaped_unicode6.in
output:
registers:
r:
type: char
value: a
value: "'a'"
- input_file: inputs/escaped.in
output:
registers:
r:
type: char
value: a
value: "'a'"
- input_file: inputs/hex1.in
output:
registers:
r:
type: char
value: a
value: "'a'"
- input_file: inputs/hex2.in
output:
registers:
r:
type: char
value: a
value: "'a'"
- input_file: inputs/unicode1.in
output:
registers:
r:
type: char
value: a
value: "'a'"
- input_file: inputs/unicode2.in
output:
registers:
r:
type: char
value: a
value: "'a'"
- input_file: inputs/unicode3.in
output:
registers:
r:
type: char
value: a
value: "'a'"
- input_file: inputs/unicode4.in
output:
registers:
r:
type: char
value: a
value: "'a'"
- input_file: inputs/unicode5.in
output:
registers:
r:
type: char
value: a
value: "'a'"

View File

@ -15,7 +15,7 @@ outputs:
registers:
r0:
type: "[char; 33]"
value: "\\u{0}\\u{1}\\u{2}\\u{3}\\u{4}\\u{5}\\u{6}\\u{7}\\u{8}\\t\\n\\u{b}\\u{c}\\r\\u{e}\\u{f}\\u{10}\\u{11}\\u{12}\\u{13}\\u{14}\\u{15}\\u{16}\\u{17}\\u{18}\\u{19}\\u{1a}\\u{1b}\\u{1c}\\u{1d}\\u{1e}\\u{1f}\\u{1f}"
value: "\"\\u{0}\\u{1}\\u{2}\\u{3}\\u{4}\\u{5}\\u{6}\\u{7}\\u{8}\\t\\n\\u{b}\\u{c}\\r\\u{e}\\u{f}\\u{10}\\u{11}\\u{12}\\u{13}\\u{14}\\u{15}\\u{16}\\u{17}\\u{18}\\u{19}\\u{1a}\\u{1b}\\u{1c}\\u{1d}\\u{1e}\\u{1f}\\u{1f}\""
r1:
type: bool
value: "true"

View File

@ -15,88 +15,88 @@ outputs:
registers:
r:
type: char
value: a
value: "'a'"
- input_file: inputs/escaped_unicode1.in
output:
registers:
r:
type: char
value: "\\u{f}"
value: "'\\u{f}'"
- input_file: inputs/escaped_unicode2.in
output:
registers:
r:
type: char
value: "\\u{e5}"
value: "'å'"
- input_file: inputs/escaped_unicode3.in
output:
registers:
r:
type: char
value: "\\u{4e0}"
value: "'Ӡ'"
- input_file: inputs/escaped_unicode4.in
output:
registers:
r:
type: char
value: "\\u{2764}"
value: "'\\u{2764}'"
- input_file: inputs/escaped_unicode5.in
output:
registers:
r:
type: char
value: "\\u{1f622}"
value: "'\\u{1f622}'"
- input_file: inputs/escaped_unicode6.in
output:
registers:
r:
type: char
value: "\\u{10001f}"
value: "'\\u{10001f}'"
- input_file: inputs/escaped.in
output:
registers:
r:
type: char
value: "\\'"
value: "'\\''"
- input_file: inputs/hex1.in
output:
registers:
r:
type: char
value: "*"
value: "'*'"
- input_file: inputs/hex2.in
output:
registers:
r:
type: char
value: "\\u{7f}"
value: "'\\u{7f}'"
- input_file: inputs/unicode1.in
output:
registers:
r:
type: char
value: "\\u{e00f}"
value: "'\\u{e00f}'"
- input_file: inputs/unicode2.in
output:
registers:
r:
type: char
value: "\\u{e5}"
value: "'å'"
- input_file: inputs/unicode3.in
output:
registers:
r:
type: char
value: "\\u{4e0}"
value: "'Ӡ'"
- input_file: inputs/unicode4.in
output:
registers:
r:
type: char
value: "\\u{2764}"
value: "'\\u{2764}'"
- input_file: inputs/unicode5.in
output:
registers:
r:
type: char
value: "\\u{1f62d}"
value: "'\\u{1f62d}'"

View File

@ -15,4 +15,4 @@ outputs:
registers:
r2:
type: "[[u8; 4]; 2]"
value: "[[0, 0, 0, 0], [0, 0, 0, 0]]"
value: "\"[0, 0, 0, 0][0, 0, 0, 0]\""

View File

@ -15,10 +15,10 @@ outputs:
registers:
r0:
type: "[u32; 3]"
value: "[3, 0, 3]"
value: "\"303\""
- input_file: input/index2.in
output:
registers:
r0:
type: "[u32; 3]"
value: "[1, 5, 0]"
value: "\"150\""

View File

@ -15,10 +15,10 @@ outputs:
registers:
r0:
type: "[(u32, u32); 3]"
value: "[(1, 1), (0, 1), (3, 3)]"
value: "\"(1, 1)(0, 1)(3, 3)\""
- input_file: input/index2_tuple.in
output:
registers:
r0:
type: "[(u32, u32); 3]"
value: "[(1, 1), (2, 2), (0, 1)]"
value: "\"(1, 1)(2, 2)(0, 1)\""

View File

@ -15,4 +15,4 @@ outputs:
registers:
out:
type: "[char; 13]"
value: "Hello, World!"
value: "\"Hello, World!\""

View File

@ -4,8 +4,10 @@ expectation: Pass
outputs:
- Value:
Char:
- a
- line_start: 1
character:
Scalar: 97
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 4
@ -13,8 +15,10 @@ outputs:
content: "'a'"
- Value:
Char:
- Z
- line_start: 1
character:
Scalar: 90
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 4
@ -22,8 +26,10 @@ outputs:
content: "'Z'"
- Value:
Char:
- "\""
- line_start: 1
character:
Scalar: 34
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 5
@ -31,8 +37,10 @@ outputs:
content: "'\\\"'"
- Value:
Char:
- "\t"
- line_start: 1
character:
Scalar: 9
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 5
@ -40,8 +48,10 @@ outputs:
content: "'\\t'"
- Value:
Char:
- "\r"
- line_start: 1
character:
Scalar: 13
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 5
@ -49,8 +59,10 @@ outputs:
content: "'\\r'"
- Value:
Char:
- "\u0000"
- line_start: 1
character:
Scalar: 0
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 5
@ -58,8 +70,10 @@ outputs:
content: "'\\0'"
- Value:
Char:
- "\u000f"
- line_start: 1
character:
Scalar: 15
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 8
@ -67,8 +81,10 @@ outputs:
content: "'\\u{F}'"
- Value:
Char:
- 
- line_start: 1
character:
Scalar: 57359
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 6
@ -76,8 +92,10 @@ outputs:
content: "''"
- Value:
Char:
- å
- line_start: 1
character:
Scalar: 229
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 9
@ -85,8 +103,10 @@ outputs:
content: "'\\u{E5}'"
- Value:
Char:
- å
- line_start: 1
character:
Scalar: 229
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 5
@ -94,8 +114,10 @@ outputs:
content: "'å'"
- Value:
Char:
- Ӡ
- line_start: 1
character:
Scalar: 1248
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 10
@ -103,8 +125,10 @@ outputs:
content: "'\\u{4e0}'"
- Value:
Char:
- Ӡ
- line_start: 1
character:
Scalar: 1248
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 5
@ -112,8 +136,10 @@ outputs:
content: "'Ӡ'"
- Value:
Char:
- ❤
- line_start: 1
character:
Scalar: 10084
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 11
@ -121,8 +147,10 @@ outputs:
content: "'\\u{2764}'"
- Value:
Char:
- ❤
- line_start: 1
character:
Scalar: 10084
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 6
@ -130,8 +158,10 @@ outputs:
content: "'❤'"
- Value:
Char:
- 😢
- line_start: 1
character:
Scalar: 128546
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 12
@ -139,8 +169,10 @@ outputs:
content: "'\\u{1F622}'"
- Value:
Char:
- 😭
- line_start: 1
character:
Scalar: 128557
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -148,8 +180,10 @@ outputs:
content: "'😭'"
- Value:
Char:
- 􀀟
- line_start: 1
character:
Scalar: 1048607
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 13
@ -157,8 +191,10 @@ outputs:
content: "'\\u{10001F}'"
- Value:
Char:
- "*"
- line_start: 1
character:
Scalar: 42
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -166,8 +202,10 @@ outputs:
content: "'\\x2A'"
- Value:
Char:
- 
- line_start: 1
character:
Scalar: 127
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -175,8 +213,10 @@ outputs:
content: "'\\x7f'"
- Value:
Char:
- "\u0000"
- line_start: 1
character:
Scalar: 0
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -184,8 +224,10 @@ outputs:
content: "'\\x00'"
- Value:
Char:
- "\u0001"
- line_start: 1
character:
Scalar: 1
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -193,8 +235,10 @@ outputs:
content: "'\\x01'"
- Value:
Char:
- "\u0002"
- line_start: 1
character:
Scalar: 2
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -202,8 +246,10 @@ outputs:
content: "'\\x02'"
- Value:
Char:
- "\u0003"
- line_start: 1
character:
Scalar: 3
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -211,8 +257,10 @@ outputs:
content: "'\\x03'"
- Value:
Char:
- "\u0004"
- line_start: 1
character:
Scalar: 4
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -220,8 +268,10 @@ outputs:
content: "'\\x04'"
- Value:
Char:
- "\u0005"
- line_start: 1
character:
Scalar: 5
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -229,8 +279,10 @@ outputs:
content: "'\\x05'"
- Value:
Char:
- "\u0006"
- line_start: 1
character:
Scalar: 6
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -238,8 +290,10 @@ outputs:
content: "'\\x06'"
- Value:
Char:
- 
- line_start: 1
character:
Scalar: 7
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -247,8 +301,10 @@ outputs:
content: "'\\x07'"
- Value:
Char:
- "\u0010"
- line_start: 1
character:
Scalar: 16
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -256,8 +312,10 @@ outputs:
content: "'\\x10'"
- Value:
Char:
- "\u0011"
- line_start: 1
character:
Scalar: 17
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -265,8 +323,10 @@ outputs:
content: "'\\x11'"
- Value:
Char:
- "\u0012"
- line_start: 1
character:
Scalar: 18
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -274,8 +334,10 @@ outputs:
content: "'\\x12'"
- Value:
Char:
- "\u0013"
- line_start: 1
character:
Scalar: 19
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -283,8 +345,10 @@ outputs:
content: "'\\x13'"
- Value:
Char:
- "\u0014"
- line_start: 1
character:
Scalar: 20
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -292,8 +356,10 @@ outputs:
content: "'\\x14'"
- Value:
Char:
- "\u0015"
- line_start: 1
character:
Scalar: 21
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -301,8 +367,10 @@ outputs:
content: "'\\x15'"
- Value:
Char:
- "\u0016"
- line_start: 1
character:
Scalar: 22
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -310,8 +378,10 @@ outputs:
content: "'\\x16'"
- Value:
Char:
- "\u0017"
- line_start: 1
character:
Scalar: 23
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -319,8 +389,10 @@ outputs:
content: "'\\x17'"
- Value:
Char:
- " "
- line_start: 1
character:
Scalar: 32
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -328,8 +400,10 @@ outputs:
content: "'\\x20'"
- Value:
Char:
- "!"
- line_start: 1
character:
Scalar: 33
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -337,8 +411,10 @@ outputs:
content: "'\\x21'"
- Value:
Char:
- "\""
- line_start: 1
character:
Scalar: 34
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -346,8 +422,10 @@ outputs:
content: "'\\x22'"
- Value:
Char:
- "#"
- line_start: 1
character:
Scalar: 35
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -355,8 +433,10 @@ outputs:
content: "'\\x23'"
- Value:
Char:
- $
- line_start: 1
character:
Scalar: 36
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -364,8 +444,10 @@ outputs:
content: "'\\x24'"
- Value:
Char:
- "%"
- line_start: 1
character:
Scalar: 37
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -373,8 +455,10 @@ outputs:
content: "'\\x25'"
- Value:
Char:
- "&"
- line_start: 1
character:
Scalar: 38
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -382,8 +466,10 @@ outputs:
content: "'\\x26'"
- Value:
Char:
- "'"
- line_start: 1
character:
Scalar: 39
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -391,8 +477,10 @@ outputs:
content: "'\\x27'"
- Value:
Char:
- "0"
- line_start: 1
character:
Scalar: 48
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -400,8 +488,10 @@ outputs:
content: "'\\x30'"
- Value:
Char:
- "1"
- line_start: 1
character:
Scalar: 49
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -409,8 +499,10 @@ outputs:
content: "'\\x31'"
- Value:
Char:
- "2"
- line_start: 1
character:
Scalar: 50
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -418,8 +510,10 @@ outputs:
content: "'\\x32'"
- Value:
Char:
- "3"
- line_start: 1
character:
Scalar: 51
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -427,8 +521,10 @@ outputs:
content: "'\\x33'"
- Value:
Char:
- "4"
- line_start: 1
character:
Scalar: 52
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -436,8 +532,10 @@ outputs:
content: "'\\x34'"
- Value:
Char:
- "5"
- line_start: 1
character:
Scalar: 53
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -445,8 +543,10 @@ outputs:
content: "'\\x35'"
- Value:
Char:
- "6"
- line_start: 1
character:
Scalar: 54
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7
@ -454,8 +554,10 @@ outputs:
content: "'\\x36'"
- Value:
Char:
- "7"
- line_start: 1
character:
Scalar: 55
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 7

View File

@ -4,7 +4,12 @@ expectation: Pass
outputs:
- Value:
String:
- string
- - Scalar: 115
- Scalar: 116
- Scalar: 114
- Scalar: 105
- Scalar: 110
- Scalar: 103
- line_start: 1
line_stop: 1
col_start: 1
@ -13,7 +18,24 @@ outputs:
content: "\"string\""
- Value:
String:
- "another { } string"
- - Scalar: 97
- Scalar: 110
- Scalar: 111
- Scalar: 116
- Scalar: 104
- Scalar: 101
- Scalar: 114
- Scalar: 32
- Scalar: 123
- Scalar: 32
- Scalar: 125
- Scalar: 32
- Scalar: 115
- Scalar: 116
- Scalar: 114
- Scalar: 105
- Scalar: 110
- Scalar: 103
- line_start: 1
line_stop: 1
col_start: 1
@ -22,7 +44,15 @@ outputs:
content: "\"another { } string\""
- Value:
String:
- "{ ] [ ; a"
- - Scalar: 123
- Scalar: 32
- Scalar: 93
- Scalar: 32
- Scalar: 91
- Scalar: 32
- Scalar: 59
- Scalar: 32
- Scalar: 97
- line_start: 1
line_stop: 1
col_start: 1
@ -31,7 +61,7 @@ outputs:
content: "\"{ ] [ ; a\""
- Value:
String:
-
- - Scalar: 4090
- line_start: 1
line_stop: 1
col_start: 1
@ -40,7 +70,7 @@ outputs:
content: "\"\\u{FFA}\""
- Value:
String:
- 򯫺
- - Scalar: 719610
- line_start: 1
line_stop: 1
col_start: 1
@ -49,7 +79,7 @@ outputs:
content: "\"\\u{afafa}\""
- Value:
String:
-
- - Scalar: 44975
- line_start: 1
line_stop: 1
col_start: 1
@ -58,7 +88,7 @@ outputs:
content: "\"\\u{afaf}\""
- Value:
String:
-
- - Scalar: 2810
- line_start: 1
line_stop: 1
col_start: 1
@ -67,7 +97,7 @@ outputs:
content: "\"\\u{afa}\""
- Value:
String:
- ¯
- - Scalar: 175
- line_start: 1
line_stop: 1
col_start: 1
@ -76,7 +106,7 @@ outputs:
content: "\"\\u{af}\""
- Value:
String:
- "\n"
- - Scalar: 10
- line_start: 1
line_stop: 1
col_start: 1
@ -85,7 +115,7 @@ outputs:
content: "\"\\u{a}\""
- Value:
String:
- "\n"
- - Scalar: 10
- line_start: 1
line_stop: 1
col_start: 1
@ -94,7 +124,7 @@ outputs:
content: "\"\\x0A\""
- Value:
String:
- 
- - Scalar: 127
- line_start: 1
line_stop: 1
col_start: 1
@ -103,7 +133,25 @@ outputs:
content: "\"\\x7F\""
- Value:
String:
- "aa \\ \" \n aa \t \r \u0000"
- - Scalar: 97
- Scalar: 97
- Scalar: 32
- Scalar: 92
- Scalar: 32
- Scalar: 34
- Scalar: 32
- Scalar: 32
- Scalar: 10
- Scalar: 32
- Scalar: 97
- Scalar: 97
- Scalar: 32
- Scalar: 9
- Scalar: 32
- Scalar: 13
- Scalar: 32
- Scalar: 32
- Scalar: 0
- line_start: 1
line_stop: 1
col_start: 1
@ -112,7 +160,13 @@ outputs:
content: "\"aa \\\\ \\\" \\n aa \\t \\r \\0\""
- Value:
String:
- test 😒€
- - Scalar: 116
- Scalar: 101
- Scalar: 115
- Scalar: 116
- Scalar: 32
- Scalar: 128530
- Scalar: 8364
- line_start: 1
line_stop: 1
col_start: 1
@ -121,7 +175,9 @@ outputs:
content: "\"test 😒€\""
- Value:
String:
- 😭😂😘
- - Scalar: 128557
- Scalar: 128514
- Scalar: 128536
- line_start: 1
line_stop: 1
col_start: 1

View File

@ -41,7 +41,7 @@ outputs:
parts:
- Const: ""
- Container
- Const: "{}"
- Const: ""
- Container
parameters:
- Identifier: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":23,\\\"col_stop\\\":24,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"console.error(\\\\\\\"{}{}\\\\\\\", x, y);\\\"}\"}"
@ -63,7 +63,8 @@ outputs:
- Console:
function:
Error:
parts: []
parts:
- Const: x
parameters: []
span:
line_start: 1
@ -107,7 +108,7 @@ outputs:
parts:
- Const: ""
- Container
- Const: "{}"
- Const: ""
- Container
parameters:
- Identifier: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":23,\\\"col_stop\\\":24,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"console.debug(\\\\\\\"{}{}\\\\\\\", x, y);\\\"}\"}"
@ -129,7 +130,8 @@ outputs:
- Console:
function:
Debug:
parts: []
parts:
- Const: x
parameters: []
span:
line_start: 1
@ -173,7 +175,7 @@ outputs:
parts:
- Const: ""
- Container
- Const: "{}"
- Const: ""
- Container
parameters:
- Identifier: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":21,\\\"col_stop\\\":22,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"console.log(\\\\\\\"{}{}\\\\\\\", x, y);\\\"}\"}"
@ -195,7 +197,8 @@ outputs:
- Console:
function:
Log:
parts: []
parts:
- Const: x
parameters: []
span:
line_start: 1