mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-24 18:39:50 -04:00
refactor: Use Rc<str> instead of string
This commit is contained in:
parent
b07147367c
commit
a301ff7dfe
@ -125,18 +125,18 @@ pub enum TokenType {
|
|||||||
#[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
|
#[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
|
||||||
pub struct Token {
|
pub struct Token {
|
||||||
pub typ: TokenType,
|
pub typ: TokenType,
|
||||||
pub fragment: String,
|
pub fragment: Rc<str>,
|
||||||
pub pos: Position,
|
pub pos: Position,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Token {
|
impl Token {
|
||||||
/// Constructs a new Token with a type and line and column information.
|
/// Constructs a new Token with a type and line and column information.
|
||||||
pub fn new<S: Into<String>, P: Into<Position>>(f: S, typ: TokenType, p: P) -> Self {
|
pub fn new<S: Into<Rc<str>>, P: Into<Position>>(f: S, typ: TokenType, p: P) -> Self {
|
||||||
Self::new_with_pos(f, typ, p.into())
|
Self::new_with_pos(f, typ, p.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructs a new Token with a type and a Position.
|
// Constructs a new Token with a type and a Position.
|
||||||
pub fn new_with_pos<S: Into<String>>(f: S, typ: TokenType, pos: Position) -> Self {
|
pub fn new_with_pos<S: Into<Rc<str>>>(f: S, typ: TokenType, pos: Position) -> Self {
|
||||||
Token {
|
Token {
|
||||||
typ,
|
typ,
|
||||||
fragment: f.into(),
|
fragment: f.into(),
|
||||||
@ -241,8 +241,8 @@ pub enum Value {
|
|||||||
Boolean(PositionedItem<bool>),
|
Boolean(PositionedItem<bool>),
|
||||||
Int(PositionedItem<i64>),
|
Int(PositionedItem<i64>),
|
||||||
Float(PositionedItem<f64>),
|
Float(PositionedItem<f64>),
|
||||||
Str(PositionedItem<String>),
|
Str(PositionedItem<Rc<str>>),
|
||||||
Symbol(PositionedItem<String>),
|
Symbol(PositionedItem<Rc<str>>),
|
||||||
Tuple(PositionedItem<FieldList>),
|
Tuple(PositionedItem<FieldList>),
|
||||||
List(ListDef),
|
List(ListDef),
|
||||||
}
|
}
|
||||||
@ -250,7 +250,7 @@ pub enum Value {
|
|||||||
#[derive(PartialEq, Debug, Clone)]
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
pub enum ImportShape {
|
pub enum ImportShape {
|
||||||
Resolved(Position, TupleShape),
|
Resolved(Position, TupleShape),
|
||||||
Unresolved(PositionedItem<String>),
|
Unresolved(PositionedItem<Rc<str>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Clone)]
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
@ -281,15 +281,15 @@ pub enum Shape {
|
|||||||
Boolean(PositionedItem<bool>),
|
Boolean(PositionedItem<bool>),
|
||||||
Int(PositionedItem<i64>),
|
Int(PositionedItem<i64>),
|
||||||
Float(PositionedItem<f64>),
|
Float(PositionedItem<f64>),
|
||||||
Str(PositionedItem<String>),
|
Str(PositionedItem<Rc<str>>),
|
||||||
Tuple(PositionedItem<TupleShape>),
|
Tuple(PositionedItem<TupleShape>),
|
||||||
List(NarrowedShape),
|
List(NarrowedShape),
|
||||||
Func(FuncShapeDef),
|
Func(FuncShapeDef),
|
||||||
Module(ModuleShape),
|
Module(ModuleShape),
|
||||||
Hole(PositionedItem<String>), // A type hole We don't know what this type is yet.
|
Hole(PositionedItem<Rc<str>>), // A type hole We don't know what this type is yet.
|
||||||
Narrowed(NarrowedShape), // A narrowed type. We know *some* of the possible options.
|
Narrowed(NarrowedShape), // A narrowed type. We know *some* of the possible options.
|
||||||
Import(ImportShape), // A type hole We don't know what this type is yet.
|
Import(ImportShape), // A type hole We don't know what this type is yet.
|
||||||
TypeErr(Position, String), // A type hole We don't know what this type is yet.
|
TypeErr(Position, String), // A type hole We don't know what this type is yet.
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Shape {
|
impl Shape {
|
||||||
@ -327,7 +327,12 @@ impl Shape {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn narrow_tuple_shapes(&self, left_slist: &PositionedItem<Vec<(Token, Shape)>>, right_slist: &PositionedItem<Vec<(Token, Shape)>>, right: &Shape) -> Shape {
|
fn narrow_tuple_shapes(
|
||||||
|
&self,
|
||||||
|
left_slist: &PositionedItem<Vec<(Token, Shape)>>,
|
||||||
|
right_slist: &PositionedItem<Vec<(Token, Shape)>>,
|
||||||
|
right: &Shape,
|
||||||
|
) -> Shape {
|
||||||
let left_iter = left_slist.val.iter();
|
let left_iter = left_slist.val.iter();
|
||||||
let right_iter = right_slist.val.iter();
|
let right_iter = right_slist.val.iter();
|
||||||
if is_tuple_subset(left_iter, right_slist) {
|
if is_tuple_subset(left_iter, right_slist) {
|
||||||
@ -542,7 +547,7 @@ impl Value {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn derive_shape(&self, symbol_table: &mut BTreeMap<String, Shape>) -> Shape {
|
fn derive_shape(&self, symbol_table: &mut BTreeMap<Rc<str>, Shape>) -> Shape {
|
||||||
let shape = match self {
|
let shape = match self {
|
||||||
Value::Empty(p) => Shape::Empty(p.clone()),
|
Value::Empty(p) => Shape::Empty(p.clone()),
|
||||||
Value::Boolean(p) => Shape::Boolean(p.clone()),
|
Value::Boolean(p) => Shape::Boolean(p.clone()),
|
||||||
@ -690,8 +695,8 @@ impl<'a> From<&'a Token> for PositionedItem<String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a PositionedItem<String>> for PositionedItem<String> {
|
impl<'a> From<&'a PositionedItem<Rc<str>>> for PositionedItem<Rc<str>> {
|
||||||
fn from(t: &PositionedItem<String>) -> PositionedItem<String> {
|
fn from(t: &PositionedItem<Rc<str>>) -> PositionedItem<Rc<str>> {
|
||||||
PositionedItem {
|
PositionedItem {
|
||||||
pos: t.pos.clone(),
|
pos: t.pos.clone(),
|
||||||
val: t.val.clone(),
|
val: t.val.clone(),
|
||||||
@ -705,7 +710,7 @@ impl<'a> From<&'a PositionedItem<String>> for PositionedItem<String> {
|
|||||||
#[derive(PartialEq, Debug, Clone)]
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
pub struct FuncDef {
|
pub struct FuncDef {
|
||||||
pub scope: Option<Scope>,
|
pub scope: Option<Scope>,
|
||||||
pub argdefs: Vec<PositionedItem<String>>,
|
pub argdefs: Vec<PositionedItem<Rc<str>>>,
|
||||||
pub fields: Box<Expression>,
|
pub fields: Box<Expression>,
|
||||||
pub pos: Position,
|
pub pos: Position,
|
||||||
}
|
}
|
||||||
@ -713,7 +718,11 @@ pub struct FuncDef {
|
|||||||
impl FuncDef {
|
impl FuncDef {
|
||||||
fn derive_shape(&self) -> Shape {
|
fn derive_shape(&self) -> Shape {
|
||||||
// 1. First set up our symbols.
|
// 1. First set up our symbols.
|
||||||
let _table = self.argdefs.iter().map(|sym| (sym.val.clone(), Shape::Hole(sym.clone()))).collect::<BTreeMap<String, Shape>>();
|
let _table = self
|
||||||
|
.argdefs
|
||||||
|
.iter()
|
||||||
|
.map(|sym| (sym.val.clone(), Shape::Hole(sym.clone())))
|
||||||
|
.collect::<BTreeMap<Rc<str>, Shape>>();
|
||||||
// 2.Then determine the shapes of those symbols in our expression.
|
// 2.Then determine the shapes of those symbols in our expression.
|
||||||
// 3. Finally determine what the return shape can be.
|
// 3. Finally determine what the return shape can be.
|
||||||
todo!();
|
todo!();
|
||||||
@ -983,11 +992,11 @@ impl Expression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn derive_shape(&self, symbol_table: &mut BTreeMap<String, Shape>) -> Shape {
|
fn derive_shape(&self, symbol_table: &mut BTreeMap<Rc<str>, Shape>) -> Shape {
|
||||||
let shape = match self {
|
let shape = match self {
|
||||||
Expression::Simple(v) => v.derive_shape(symbol_table),
|
Expression::Simple(v) => v.derive_shape(symbol_table),
|
||||||
Expression::Format(def) => {
|
Expression::Format(def) => {
|
||||||
Shape::Str(PositionedItem::new("".to_owned(), def.pos.clone()))
|
Shape::Str(PositionedItem::new("".into(), def.pos.clone()))
|
||||||
}
|
}
|
||||||
Expression::Not(def) => derive_not_shape(def, symbol_table),
|
Expression::Not(def) => derive_not_shape(def, symbol_table),
|
||||||
Expression::Grouped(v, _pos) => v.as_ref().derive_shape(symbol_table),
|
Expression::Grouped(v, _pos) => v.as_ref().derive_shape(symbol_table),
|
||||||
@ -997,7 +1006,7 @@ impl Expression {
|
|||||||
)),
|
)),
|
||||||
Expression::Cast(def) => match def.cast_type {
|
Expression::Cast(def) => match def.cast_type {
|
||||||
CastType::Int => Shape::Int(PositionedItem::new(0, def.pos.clone())),
|
CastType::Int => Shape::Int(PositionedItem::new(0, def.pos.clone())),
|
||||||
CastType::Str => Shape::Str(PositionedItem::new("".to_owned(), def.pos.clone())),
|
CastType::Str => Shape::Str(PositionedItem::new("".into(), def.pos.clone())),
|
||||||
CastType::Float => Shape::Float(PositionedItem::new(0.0, def.pos.clone())),
|
CastType::Float => Shape::Float(PositionedItem::new(0.0, def.pos.clone())),
|
||||||
CastType::Bool => Shape::Boolean(PositionedItem::new(true, def.pos.clone())),
|
CastType::Bool => Shape::Boolean(PositionedItem::new(true, def.pos.clone())),
|
||||||
},
|
},
|
||||||
@ -1040,7 +1049,7 @@ fn derive_include_shape(
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn derive_not_shape(def: &NotDef, symbol_table: &mut BTreeMap<String, Shape>) -> Shape {
|
fn derive_not_shape(def: &NotDef, symbol_table: &mut BTreeMap<Rc<str>, Shape>) -> Shape {
|
||||||
let shape = def.expr.as_ref().derive_shape(symbol_table);
|
let shape = def.expr.as_ref().derive_shape(symbol_table);
|
||||||
if let Shape::Boolean(b) = shape {
|
if let Shape::Boolean(b) = shape {
|
||||||
Shape::Boolean(PositionedItem::new(!b.val, def.pos.clone()))
|
Shape::Boolean(PositionedItem::new(!b.val, def.pos.clone()))
|
||||||
@ -1056,7 +1065,7 @@ fn derive_not_shape(def: &NotDef, symbol_table: &mut BTreeMap<String, Shape>) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn derive_copy_shape(def: &CopyDef, symbol_table: &mut BTreeMap<String, Shape>) -> Shape {
|
fn derive_copy_shape(def: &CopyDef, symbol_table: &mut BTreeMap<Rc<str>, Shape>) -> Shape {
|
||||||
let base_shape = def.selector.derive_shape(symbol_table);
|
let base_shape = def.selector.derive_shape(symbol_table);
|
||||||
match &base_shape {
|
match &base_shape {
|
||||||
// TODO(jwall): Should we allow a stack of these?
|
// TODO(jwall): Should we allow a stack of these?
|
||||||
@ -1113,7 +1122,7 @@ fn derive_copy_shape(def: &CopyDef, symbol_table: &mut BTreeMap<String, Shape>)
|
|||||||
.fields
|
.fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(tok, expr)| (tok.fragment.clone(), expr.derive_shape(symbol_table)))
|
.map(|(tok, expr)| (tok.fragment.clone(), expr.derive_shape(symbol_table)))
|
||||||
.collect::<BTreeMap<String, Shape>>();
|
.collect::<BTreeMap<Rc<str>, Shape>>();
|
||||||
// 1. Do our copyable fields have the right names and shapes based on mdef.items.
|
// 1. Do our copyable fields have the right names and shapes based on mdef.items.
|
||||||
for (tok, shape) in mdef.items.iter() {
|
for (tok, shape) in mdef.items.iter() {
|
||||||
if let Some(s) = arg_fields.get(&tok.fragment) {
|
if let Some(s) = arg_fields.get(&tok.fragment) {
|
||||||
|
@ -31,9 +31,9 @@ impl Visitor for Rewriter {
|
|||||||
// Rewrite all paths except for stdlib paths to absolute.
|
// Rewrite all paths except for stdlib paths to absolute.
|
||||||
let main_separator = format!("{}", std::path::MAIN_SEPARATOR);
|
let main_separator = format!("{}", std::path::MAIN_SEPARATOR);
|
||||||
if let Expression::Include(ref mut def) = expr {
|
if let Expression::Include(ref mut def) = expr {
|
||||||
let path = PathBuf::from(&def.path.fragment);
|
let path = PathBuf::from(def.path.fragment.as_ref());
|
||||||
if path.is_relative() {
|
if path.is_relative() {
|
||||||
def.path.fragment = self.base.join(path).to_string_lossy().to_string();
|
def.path.fragment = self.base.join(path).to_string_lossy().to_string().into();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Expression::Import(ref mut def) = expr {
|
if let Expression::Import(ref mut def) = expr {
|
||||||
@ -48,7 +48,7 @@ impl Visitor for Rewriter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if path.is_relative() {
|
if path.is_relative() {
|
||||||
def.path.fragment = self.base.join(path).to_string_lossy().to_string();
|
def.path.fragment = self.base.join(path).to_string_lossy().to_string().into();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,11 +46,11 @@ fn derive_shape_values() {
|
|||||||
),
|
),
|
||||||
(
|
(
|
||||||
Value::Str(PositionedItem::new(
|
Value::Str(PositionedItem::new(
|
||||||
"foo".to_owned(),
|
"foo".into(),
|
||||||
Position::new(0, 1, 2),
|
Position::new(0, 1, 2),
|
||||||
)),
|
)),
|
||||||
Shape::Str(PositionedItem::new(
|
Shape::Str(PositionedItem::new(
|
||||||
"foo".to_owned(),
|
"foo".into(),
|
||||||
Position::new(0, 1, 2),
|
Position::new(0, 1, 2),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
@ -103,7 +103,7 @@ fn derive_shape_expressions() {
|
|||||||
),
|
),
|
||||||
(
|
(
|
||||||
"\"foo {}\" % (1);",
|
"\"foo {}\" % (1);",
|
||||||
Shape::Str(PositionedItem::new("".to_owned(), Position::new(0, 0, 0))),
|
Shape::Str(PositionedItem::new("".into(), Position::new(0, 0, 0))),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"not true;",
|
"not true;",
|
||||||
@ -112,8 +112,8 @@ fn derive_shape_expressions() {
|
|||||||
(
|
(
|
||||||
"0:1;",
|
"0:1;",
|
||||||
Shape::List(NarrowedShape::new_with_pos(
|
Shape::List(NarrowedShape::new_with_pos(
|
||||||
vec![Shape::Int(PositionedItem::new(0, Position::new(0, 0, 0)))],
|
vec![Shape::Int(PositionedItem::new(0, Position::new(1, 1, 0)))],
|
||||||
Position::new(0, 0, 0),
|
Position::new(1, 1, 0),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -126,7 +126,7 @@ fn derive_shape_expressions() {
|
|||||||
),
|
),
|
||||||
(
|
(
|
||||||
"str(1);",
|
"str(1);",
|
||||||
Shape::Str(PositionedItem::new("".to_owned(), Position::new(0, 0, 0))),
|
Shape::Str(PositionedItem::new("".into(), Position::new(0, 0, 0))),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"bool(\"true\");",
|
"bool(\"true\");",
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
//! Implements typechecking for the parsed ucg AST.
|
//! Implements typechecking for the parsed ucg AST.
|
||||||
// FIXME(jwall): This probably just needs to disappear now.
|
// FIXME(jwall): This probably just needs to disappear now.
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::ast::walk::Visitor;
|
use crate::ast::walk::Visitor;
|
||||||
use crate::ast::{Expression, FailDef, ImportDef, IncludeDef, Position, Shape, Statement, Value};
|
use crate::ast::{Expression, FailDef, ImportDef, IncludeDef, Position, Shape, Statement, Value};
|
||||||
@ -28,7 +29,7 @@ use Statement::Let;
|
|||||||
use Value::{Boolean, Empty, Float, Int, List, Str, Symbol, Tuple};
|
use Value::{Boolean, Empty, Float, Int, List, Str, Symbol, Tuple};
|
||||||
|
|
||||||
pub struct Checker {
|
pub struct Checker {
|
||||||
symbol_table: BTreeMap<String, Shape>,
|
symbol_table: BTreeMap<Rc<str>, Shape>,
|
||||||
err_stack: Vec<BuildError>,
|
err_stack: Vec<BuildError>,
|
||||||
shape_stack: Vec<Shape>,
|
shape_stack: Vec<Shape>,
|
||||||
}
|
}
|
||||||
@ -46,7 +47,7 @@ impl Checker {
|
|||||||
self.shape_stack.pop()
|
self.shape_stack.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn result(mut self) -> Result<BTreeMap<String, Shape>, BuildError> {
|
pub fn result(mut self) -> Result<BTreeMap<Rc<str>, Shape>, BuildError> {
|
||||||
if let Some(err) = self.err_stack.pop() {
|
if let Some(err) = self.err_stack.pop() {
|
||||||
Err(err)
|
Err(err)
|
||||||
} else {
|
} else {
|
||||||
|
@ -45,7 +45,7 @@ fn simple_binary_typecheck() {
|
|||||||
);
|
);
|
||||||
assert_type_success!(
|
assert_type_success!(
|
||||||
"\"\" + \"\";",
|
"\"\" + \"\";",
|
||||||
Shape::Str(PositionedItem::new(String::new(), Position::new(1, 1, 0)))
|
Shape::Str(PositionedItem::new("".into(), Position::new(1, 1, 0)))
|
||||||
);
|
);
|
||||||
assert_type_success!(
|
assert_type_success!(
|
||||||
"1.0 + 1.0;",
|
"1.0 + 1.0;",
|
||||||
@ -64,7 +64,7 @@ fn simple_binary_typecheck() {
|
|||||||
"{foo = 1} + {foo = 1};",
|
"{foo = 1} + {foo = 1};",
|
||||||
Shape::Tuple(PositionedItem::new(
|
Shape::Tuple(PositionedItem::new(
|
||||||
vec![
|
vec![
|
||||||
(Token { typ: TokenType::BAREWORD, fragment: "foo".to_owned(), pos: Position::new(1, 2, 1)},
|
(Token { typ: TokenType::BAREWORD, fragment: "foo".into(), pos: Position::new(1, 2, 1)},
|
||||||
Shape::Int(PositionedItem::new_with_pos(1, Position::new(1, 8, 7)))),
|
Shape::Int(PositionedItem::new_with_pos(1, Position::new(1, 8, 7)))),
|
||||||
],
|
],
|
||||||
Position::new(1, 1, 0)
|
Position::new(1, 1, 0)
|
||||||
|
@ -26,7 +26,7 @@ fn assert_build(input: &str) {
|
|||||||
let out_buffer: Vec<u8> = Vec::new();
|
let out_buffer: Vec<u8> = Vec::new();
|
||||||
let err_buffer: Vec<u8> = Vec::new();
|
let err_buffer: Vec<u8> = Vec::new();
|
||||||
let mut env_vars = BTreeMap::new();
|
let mut env_vars = BTreeMap::new();
|
||||||
env_vars.insert("FOO".to_owned(), "bar".to_owned());
|
env_vars.insert("FOO".into(), "bar".into());
|
||||||
let env = RefCell::new(Environment::new_with_vars(out_buffer, err_buffer, env_vars));
|
let env = RefCell::new(Environment::new_with_vars(out_buffer, err_buffer, env_vars));
|
||||||
let mut b = FileBuilder::new("<Eval>", &i_paths, &env);
|
let mut b = FileBuilder::new("<Eval>", &i_paths, &env);
|
||||||
b.enable_validate_mode();
|
b.enable_validate_mode();
|
||||||
|
@ -15,10 +15,10 @@ pub enum Val {
|
|||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
Int(i64),
|
Int(i64),
|
||||||
Float(f64),
|
Float(f64),
|
||||||
Str(String),
|
Str(Rc<str>),
|
||||||
List(Vec<Rc<Val>>),
|
List(Vec<Rc<Val>>),
|
||||||
Tuple(Vec<(String, Rc<Val>)>),
|
Tuple(Vec<(Rc<str>, Rc<Val>)>),
|
||||||
Env(Vec<(String, String)>),
|
Env(Vec<(Rc<str>, Rc<str>)>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Val {
|
impl Val {
|
||||||
@ -103,7 +103,7 @@ impl Val {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the fields if this Val is a tuple. None otherwise.
|
/// Returns the fields if this Val is a tuple. None otherwise.
|
||||||
pub fn get_fields(&self) -> Option<&Vec<(String, Rc<Val>)>> {
|
pub fn get_fields(&self) -> Option<&Vec<(Rc<str>, Rc<Val>)>> {
|
||||||
if let &Val::Tuple(ref fs) = self {
|
if let &Val::Tuple(ref fs) = self {
|
||||||
Some(fs)
|
Some(fs)
|
||||||
} else {
|
} else {
|
||||||
@ -208,8 +208,8 @@ impl Display for Val {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Val> for String {
|
impl From<Val> for Rc<str> {
|
||||||
fn from(v: Val) -> String {
|
fn from(v: Val) -> Self {
|
||||||
match v {
|
match v {
|
||||||
Val::Int(ref i) => format!("{}", i),
|
Val::Int(ref i) => format!("{}", i),
|
||||||
Val::Float(ref f) => format!("{}", f),
|
Val::Float(ref f) => format!("{}", f),
|
||||||
@ -217,12 +217,12 @@ impl From<Val> for String {
|
|||||||
Val::Boolean(ref b) => format!("{}", b),
|
Val::Boolean(ref b) => format!("{}", b),
|
||||||
Val::Empty => "NULL".to_string(),
|
Val::Empty => "NULL".to_string(),
|
||||||
val => format!("{}", val),
|
val => format!("{}", val),
|
||||||
}
|
}.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<String> for Val {
|
impl From<Rc<str>> for Val {
|
||||||
fn from(s: String) -> Val {
|
fn from(s: Rc<str>) -> Val {
|
||||||
Val::Str(s)
|
Val::Str(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,7 @@ where
|
|||||||
if found.contains(&link) {
|
if found.contains(&link) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let ops = match self.environment.borrow_mut().get_ops_for_path(link.clone()) {
|
let ops = match self.environment.borrow_mut().get_ops_for_path(link.as_ref()) {
|
||||||
Ok(ops) => ops,
|
Ok(ops) => ops,
|
||||||
Err(e) => return Err(Box::new(e.with_pos(path_pos))),
|
Err(e) => return Err(Box::new(e.with_pos(path_pos))),
|
||||||
};
|
};
|
||||||
@ -343,7 +343,7 @@ where
|
|||||||
if let Some(val) = self.out.clone() {
|
if let Some(val) = self.out.clone() {
|
||||||
if let &Val::Tuple(ref flds) = val.as_ref() {
|
if let &Val::Tuple(ref flds) = val.as_ref() {
|
||||||
for (k, v) in flds.iter() {
|
for (k, v) in flds.iter() {
|
||||||
if k == name {
|
if k.as_ref() == name {
|
||||||
return Some(v.clone());
|
return Some(v.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,14 @@ impl Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&Primitive> for String {
|
impl From<&Primitive> for Rc<str> {
|
||||||
fn from(p: &Primitive) -> Self {
|
fn from(p: &Primitive) -> Self {
|
||||||
match p {
|
match p {
|
||||||
Primitive::Int(i) => format!("{}", i),
|
Primitive::Int(i) => format!("{}", i).into(),
|
||||||
Primitive::Float(f) => format!("{}", f),
|
Primitive::Float(f) => format!("{}", f).into(),
|
||||||
Primitive::Str(s) => format!("{}", s),
|
Primitive::Str(s) => format!("{}", s).into(),
|
||||||
Primitive::Bool(b) => format!("{}", b),
|
Primitive::Bool(b) => format!("{}", b).into(),
|
||||||
Primitive::Empty => "NULL".to_owned(),
|
Primitive::Empty => "NULL".into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,7 +85,7 @@ impl TryFrom<&Primitive> for bool {
|
|||||||
cast_type: CastType::Int,
|
cast_type: CastType::Int,
|
||||||
}),
|
}),
|
||||||
Primitive::Bool(b) => Ok(*b),
|
Primitive::Bool(b) => Ok(*b),
|
||||||
Primitive::Str(s) => match s.as_str() {
|
Primitive::Str(s) => match s.as_ref() {
|
||||||
"true" => Ok(true),
|
"true" => Ok(true),
|
||||||
"false" => Ok(false),
|
"false" => Ok(false),
|
||||||
_ => Err(Error {
|
_ => Err(Error {
|
||||||
@ -192,15 +192,15 @@ impl From<&Val> for Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&Composite> for String {
|
impl From<&Composite> for Rc<str> {
|
||||||
fn from(c: &Composite) -> Self {
|
fn from(c: &Composite) -> Self {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
match c {
|
match c {
|
||||||
&List(ref elems, _) => {
|
&List(ref elems, _) => {
|
||||||
buf.push_str("[");
|
buf.push_str("[");
|
||||||
for e in elems.iter() {
|
for e in elems.iter() {
|
||||||
let val: String = e.as_ref().into();
|
let val: Rc<str> = e.as_ref().into();
|
||||||
buf.push_str(&val);
|
buf.push_str(val.as_ref());
|
||||||
buf.push_str(",");
|
buf.push_str(",");
|
||||||
}
|
}
|
||||||
buf.push_str("]");
|
buf.push_str("]");
|
||||||
@ -210,26 +210,26 @@ impl From<&Composite> for String {
|
|||||||
for &(ref k, ref v) in flds.iter() {
|
for &(ref k, ref v) in flds.iter() {
|
||||||
buf.push_str(&k);
|
buf.push_str(&k);
|
||||||
buf.push_str(" = ");
|
buf.push_str(" = ");
|
||||||
let val: String = v.as_ref().into();
|
let val: Rc<str> = v.as_ref().into();
|
||||||
buf.push_str(&val);
|
buf.push_str(&val);
|
||||||
buf.push_str(",");
|
buf.push_str(",");
|
||||||
}
|
}
|
||||||
buf.push_str("}");
|
buf.push_str("}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf
|
buf.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&Value> for String {
|
impl From<&Value> for Rc<str> {
|
||||||
fn from(v: &Value) -> Self {
|
fn from(v: &Value) -> Self {
|
||||||
match v {
|
match v {
|
||||||
&S(ref s) => s.clone(),
|
&S(ref s) => s.clone(),
|
||||||
&P(ref p) => p.into(),
|
&P(ref p) => p.into(),
|
||||||
&C(ref c) => c.into(),
|
&C(ref c) => c.into(),
|
||||||
&T(_) => "<Thunk>".to_owned(),
|
&T(_) => "<Thunk>".into(),
|
||||||
&F(_) => "<Func>".to_owned(),
|
&F(_) => "<Func>".into(),
|
||||||
&M(_) => "<Module>".to_owned(),
|
&M(_) => "<Module>".into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ where
|
|||||||
Stdout: Write + Clone,
|
Stdout: Write + Clone,
|
||||||
Stderr: Write + Clone,
|
Stderr: Write + Clone,
|
||||||
{
|
{
|
||||||
pub val_cache: BTreeMap<String, Rc<Value>>,
|
pub val_cache: BTreeMap<Rc<str>, Rc<Value>>,
|
||||||
// TODO implement a shape cache here.
|
// TODO implement a shape cache here.
|
||||||
pub op_cache: cache::Ops,
|
pub op_cache: cache::Ops,
|
||||||
pub converter_registry: ConverterRegistry,
|
pub converter_registry: ConverterRegistry,
|
||||||
@ -42,7 +42,7 @@ where
|
|||||||
pub assert_results: AssertCollector,
|
pub assert_results: AssertCollector,
|
||||||
pub stdout: Stdout,
|
pub stdout: Stdout,
|
||||||
pub stderr: Stderr,
|
pub stderr: Stderr,
|
||||||
pub env_vars: BTreeMap<String, String>, // Environment Variables
|
pub env_vars: BTreeMap<Rc<str>, Rc<str>>, // Environment Variables
|
||||||
pub out_lock: BTreeSet<PathBuf>,
|
pub out_lock: BTreeSet<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ impl<Stdout: Write + Clone, Stderr: Write + Clone> Environment<Stdout, Stderr> {
|
|||||||
Self::new_with_vars(out, err, BTreeMap::new())
|
Self::new_with_vars(out, err, BTreeMap::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_vars(out: Stdout, err: Stderr, vars: BTreeMap<String, String>) -> Self {
|
pub fn new_with_vars(out: Stdout, err: Stderr, vars: BTreeMap<Rc<str>, Rc<str>>) -> Self {
|
||||||
let mut me = Self {
|
let mut me = Self {
|
||||||
val_cache: BTreeMap::new(),
|
val_cache: BTreeMap::new(),
|
||||||
env_vars: vars,
|
env_vars: vars,
|
||||||
@ -78,11 +78,11 @@ impl<Stdout: Write + Clone, Stderr: Write + Clone> Environment<Stdout, Stderr> {
|
|||||||
Value::C(Composite::Tuple(fields, positions))
|
Value::C(Composite::Tuple(fields, positions))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_cached_path_val(&self, path: &String) -> Option<Rc<Value>> {
|
pub fn get_cached_path_val(&self, path: Rc<str>) -> Option<Rc<Value>> {
|
||||||
self.val_cache.get(path).cloned()
|
self.val_cache.get(&path).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_path_val(&mut self, path: &String, val: Rc<Value>) {
|
pub fn update_path_val(&mut self, path: Rc<str>, val: Rc<Value>) {
|
||||||
self.val_cache.insert(path.clone(), val);
|
self.val_cache.insert(path.clone(), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,19 +15,20 @@ use std::convert::From;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::ast::Position;
|
use crate::ast::Position;
|
||||||
use crate::build::opcode::convert;
|
use crate::build::opcode::convert;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Error {
|
pub struct Error {
|
||||||
message: String,
|
message: Rc<str>,
|
||||||
pos: Option<Position>,
|
pos: Option<Position>,
|
||||||
call_stack: Vec<Position>,
|
call_stack: Vec<Position>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
impl Error {
|
||||||
pub fn new(msg: String, pos: Position) -> Self {
|
pub fn new(msg: Rc<str>, pos: Position) -> Self {
|
||||||
Self {
|
Self {
|
||||||
message: msg,
|
message: msg,
|
||||||
pos: Some(pos),
|
pos: Some(pos),
|
||||||
@ -69,7 +70,7 @@ macro_rules! decorate_call {
|
|||||||
impl From<regex::Error> for Error {
|
impl From<regex::Error> for Error {
|
||||||
fn from(e: regex::Error) -> Self {
|
fn from(e: regex::Error) -> Self {
|
||||||
Error {
|
Error {
|
||||||
message: format!("{}", e),
|
message: format!("{}", e).into(),
|
||||||
pos: None,
|
pos: None,
|
||||||
call_stack: Vec::new(),
|
call_stack: Vec::new(),
|
||||||
}
|
}
|
||||||
@ -83,7 +84,7 @@ impl From<std::io::Error> for Error {
|
|||||||
format!("OSError: Path not found: {}", e)
|
format!("OSError: Path not found: {}", e)
|
||||||
}
|
}
|
||||||
_ => format!("{}", e),
|
_ => format!("{}", e),
|
||||||
};
|
}.into();
|
||||||
Error {
|
Error {
|
||||||
message: msg,
|
message: msg,
|
||||||
pos: None,
|
pos: None,
|
||||||
@ -95,7 +96,7 @@ impl From<std::io::Error> for Error {
|
|||||||
impl From<convert::Error> for Error {
|
impl From<convert::Error> for Error {
|
||||||
fn from(e: convert::Error) -> Self {
|
fn from(e: convert::Error) -> Self {
|
||||||
Error {
|
Error {
|
||||||
message: e.message(),
|
message: e.message().into(),
|
||||||
pos: None,
|
pos: None,
|
||||||
call_stack: Vec::new(),
|
call_stack: Vec::new(),
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ pub enum Primitive {
|
|||||||
// Primitive Types
|
// Primitive Types
|
||||||
Int(i64),
|
Int(i64),
|
||||||
Float(f64),
|
Float(f64),
|
||||||
Str(String),
|
Str(Rc<str>),
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
Empty,
|
Empty,
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ impl Value {
|
|||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum Composite {
|
pub enum Composite {
|
||||||
List(Vec<Rc<Value>>, Vec<Position>),
|
List(Vec<Rc<Value>>, Vec<Position>),
|
||||||
Tuple(Vec<(String, Rc<Value>)>, Vec<(Position, Position)>),
|
Tuple(Vec<(Rc<str>, Rc<Value>)>, Vec<(Position, Position)>),
|
||||||
}
|
}
|
||||||
|
|
||||||
use Composite::{List, Tuple};
|
use Composite::{List, Tuple};
|
||||||
@ -75,7 +75,7 @@ use Composite::{List, Tuple};
|
|||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct Func {
|
pub struct Func {
|
||||||
ptr: OpPointer,
|
ptr: OpPointer,
|
||||||
bindings: Vec<String>,
|
bindings: Vec<Rc<str>>,
|
||||||
snapshot: Stack,
|
snapshot: Stack,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ pub struct Func {
|
|||||||
pub struct Module {
|
pub struct Module {
|
||||||
ptr: OpPointer,
|
ptr: OpPointer,
|
||||||
result_ptr: Option<usize>,
|
result_ptr: Option<usize>,
|
||||||
flds: Vec<(String, Rc<Value>)>,
|
flds: Vec<(Rc<str>, Rc<Value>)>,
|
||||||
flds_pos_list: Vec<(Position, Position)>,
|
flds_pos_list: Vec<(Position, Position)>,
|
||||||
pkg_ptr: Option<OpPointer>,
|
pkg_ptr: Option<OpPointer>,
|
||||||
}
|
}
|
||||||
@ -91,7 +91,7 @@ pub struct Module {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum Value {
|
pub enum Value {
|
||||||
// Binding names.
|
// Binding names.
|
||||||
S(String),
|
S(Rc<str>),
|
||||||
// Primitive Types
|
// Primitive Types
|
||||||
P(Primitive),
|
P(Primitive),
|
||||||
// Composite Types.
|
// Composite Types.
|
||||||
@ -147,9 +147,9 @@ pub enum Op {
|
|||||||
// Primitive casts
|
// Primitive casts
|
||||||
Cast(CastType),
|
Cast(CastType),
|
||||||
// A bareword for use in bindings or lookups
|
// A bareword for use in bindings or lookups
|
||||||
Sym(String),
|
Sym(Rc<str>),
|
||||||
// Reference a binding on the heap
|
// Reference a binding on the heap
|
||||||
DeRef(String),
|
DeRef(Rc<str>),
|
||||||
// Complex Type ops
|
// Complex Type ops
|
||||||
InitTuple,
|
InitTuple,
|
||||||
Field,
|
Field,
|
||||||
|
@ -60,7 +60,7 @@ impl OpPointer {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Err(Error::new(
|
Err(Error::new(
|
||||||
format!("FAULT!!! Invalid Jump!"),
|
"FAULT!!! Invalid Jump!".into(),
|
||||||
match self.pos() {
|
match self.pos() {
|
||||||
Some(pos) => pos.clone(),
|
Some(pos) => pos.clone(),
|
||||||
None => Position::new(0, 0, 0),
|
None => Position::new(0, 0, 0),
|
||||||
@ -86,7 +86,7 @@ impl OpPointer {
|
|||||||
match self.ptr {
|
match self.ptr {
|
||||||
Some(ptr) => Ok(ptr),
|
Some(ptr) => Ok(ptr),
|
||||||
None => Err(Error::new(
|
None => Err(Error::new(
|
||||||
format!("FAULT!!! Position Check failure!"),
|
"FAULT!!! Position Check failure!".into(),
|
||||||
Position::new(0, 0, 0),
|
Position::new(0, 0, 0),
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ impl Builtins {
|
|||||||
h: Hook,
|
h: Hook,
|
||||||
stack: &mut Vec<(Rc<Value>, Position)>,
|
stack: &mut Vec<(Rc<Value>, Position)>,
|
||||||
env: &'a RefCell<Environment<O, E>>,
|
env: &'a RefCell<Environment<O, E>>,
|
||||||
import_stack: &mut Vec<String>,
|
import_stack: &mut Vec<Rc<str>>,
|
||||||
pos: Position,
|
pos: Position,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
@ -86,19 +86,19 @@ impl Builtins {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_file_as_string(&self, path: &str) -> Result<String, Error> {
|
fn get_file_as_string(&self, path: &str) -> Result<Rc<str>, Error> {
|
||||||
let mut f = File::open(path)?;
|
let mut f = File::open(path)?;
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
// TODO(jwall): Proper error here
|
// TODO(jwall): Proper error here
|
||||||
f.read_to_string(&mut contents)?;
|
f.read_to_string(&mut contents)?;
|
||||||
Ok(contents)
|
Ok(contents.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import<'a, O, E>(
|
fn import<'a, O, E>(
|
||||||
&mut self,
|
&mut self,
|
||||||
stack: &mut Vec<(Rc<Value>, Position)>,
|
stack: &mut Vec<(Rc<Value>, Position)>,
|
||||||
env: &'a RefCell<Environment<O, E>>,
|
env: &'a RefCell<Environment<O, E>>,
|
||||||
import_stack: &mut Vec<String>,
|
import_stack: &mut Vec<Rc<str>>,
|
||||||
pos: Position,
|
pos: Position,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
@ -110,39 +110,39 @@ impl Builtins {
|
|||||||
if let &Value::P(Str(ref path)) = val.as_ref() {
|
if let &Value::P(Str(ref path)) = val.as_ref() {
|
||||||
// TODO(jwall): A bit hacky we should probably change import stacks to be pathbufs.
|
// TODO(jwall): A bit hacky we should probably change import stacks to be pathbufs.
|
||||||
// first we chack the cache
|
// first we chack the cache
|
||||||
if let Some(val) = env.borrow().get_cached_path_val(&path) {
|
if let Some(val) = env.borrow().get_cached_path_val(path.clone()) {
|
||||||
stack.push((val, path_pos));
|
stack.push((val, path_pos));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if import_stack.iter().find(|p| *p == path).is_some() {
|
if import_stack.iter().find(|p| p.as_ref() == path.as_ref()).is_some() {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Import cycle detected: {} in {:?}", path, import_stack),
|
format!("Import cycle detected: {} in {:?}", path, import_stack).into(),
|
||||||
pos,
|
pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let val = { env.borrow_mut().get_cached_path_val(&path) };
|
let val = { env.borrow_mut().get_cached_path_val(path.clone()) };
|
||||||
match val {
|
match val {
|
||||||
Some(v) => {
|
Some(v) => {
|
||||||
stack.push((v, path_pos));
|
stack.push((v, path_pos));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let path_buf = PathBuf::from(path);
|
let path_buf = PathBuf::from(path.as_ref());
|
||||||
let op_pointer =
|
let op_pointer =
|
||||||
decorate_error!(path_pos => env.borrow_mut().get_ops_for_path(&path))?;
|
decorate_error!(path_pos => env.borrow_mut().get_ops_for_path(path.as_ref()))?;
|
||||||
// TODO(jwall): What if we don't have a base path?
|
// TODO(jwall): What if we don't have a base path?
|
||||||
let mut vm =
|
let mut vm =
|
||||||
VM::with_pointer(self.strict, op_pointer, path_buf.parent().unwrap())
|
VM::with_pointer(self.strict, op_pointer, path_buf.parent().unwrap())
|
||||||
.with_import_stack(import_stack.clone());
|
.with_import_stack(import_stack.clone());
|
||||||
vm.run(env)?;
|
vm.run(env)?;
|
||||||
let result = Rc::new(vm.symbols_to_tuple(true));
|
let result = Rc::new(vm.symbols_to_tuple(true));
|
||||||
env.borrow_mut().update_path_val(&path, result.clone());
|
env.borrow_mut().update_path_val(path.clone(), result.clone());
|
||||||
stack.push((result, pos));
|
stack.push((result, pos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
import_stack.push(path.clone());
|
import_stack.push(path.clone());
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
return Err(Error::new(format!("Invalid Path {:?}", val), pos));
|
return Err(Error::new(format!("Invalid Path {:?}", val).into(), pos));
|
||||||
}
|
}
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
@ -163,7 +163,7 @@ impl Builtins {
|
|||||||
if let &Value::P(Str(ref path)) = val.as_ref() {
|
if let &Value::P(Str(ref path)) = val.as_ref() {
|
||||||
path.clone()
|
path.clone()
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(format!("Invalid Path {:?}", val), path_pos));
|
return Err(Error::new(format!("Invalid Path {:?}", val).into(), path_pos));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
@ -173,14 +173,14 @@ impl Builtins {
|
|||||||
typ.clone()
|
typ.clone()
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Expected conversion type but got {:?}", val),
|
format!("Expected conversion type but got {:?}", val).into(),
|
||||||
typ_pos,
|
typ_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
if typ == "str" {
|
if typ.as_ref() == "str" {
|
||||||
stack.push((
|
stack.push((
|
||||||
Rc::new(P(Str(self.get_file_as_string(&path)?))),
|
Rc::new(P(Str(self.get_file_as_string(&path)?))),
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
@ -196,12 +196,12 @@ impl Builtins {
|
|||||||
} else {
|
} else {
|
||||||
match importer.import(contents.as_bytes()) {
|
match importer.import(contents.as_bytes()) {
|
||||||
Ok(v) => v.into(),
|
Ok(v) => v.into(),
|
||||||
Err(e) => return Err(Error::new(format!("{}", e), pos)),
|
Err(e) => return Err(Error::new(format!("{}", e).into(), pos)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
return Err(Error::new(format!("No such conversion type {}", &typ), pos))
|
return Err(Error::new(format!("No such conversion type {}", &typ).into(), pos))
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
pos,
|
pos,
|
||||||
@ -226,10 +226,10 @@ impl Builtins {
|
|||||||
// look for the ok field.
|
// look for the ok field.
|
||||||
let mut ok = None;
|
let mut ok = None;
|
||||||
for &(ref name, ref val) in tuple_flds.iter() {
|
for &(ref name, ref val) in tuple_flds.iter() {
|
||||||
if name == "desc" {
|
if name.as_ref() == "desc" {
|
||||||
desc = Some(val.as_ref());
|
desc = Some(val.as_ref());
|
||||||
}
|
}
|
||||||
if name == "ok" {
|
if name.as_ref() == "ok" {
|
||||||
ok = Some(val.as_ref());
|
ok = Some(val.as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -284,7 +284,7 @@ impl Builtins {
|
|||||||
let write_path = path.as_ref().to_path_buf();
|
let write_path = path.as_ref().to_path_buf();
|
||||||
if env.borrow().get_out_lock_for_path(&path) {
|
if env.borrow().get_out_lock_for_path(&path) {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("You can only have one output per file"),
|
"You can only have one output per file".into(),
|
||||||
pos,
|
pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -293,7 +293,7 @@ impl Builtins {
|
|||||||
} else {
|
} else {
|
||||||
if env.borrow().get_out_lock_for_path("/dev/stdout") {
|
if env.borrow().get_out_lock_for_path("/dev/stdout") {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("You can only have one output per file"),
|
"You can only have one output per file".into(),
|
||||||
pos,
|
pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -316,18 +316,18 @@ impl Builtins {
|
|||||||
None => Box::new(stdout),
|
None => Box::new(stdout),
|
||||||
};
|
};
|
||||||
if let Err(e) = c.convert(Rc::new(val), &mut writer) {
|
if let Err(e) = c.convert(Rc::new(val), &mut writer) {
|
||||||
return Err(Error::new(format!("{}", e), pos.clone()));
|
return Err(Error::new(format!("{}", e).into(), pos.clone()));
|
||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("No such conversion type {:?}", c_type),
|
format!("No such conversion type {:?}", c_type).into(),
|
||||||
c_type_pos,
|
c_type_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Not a conversion type {:?}", c_type_val),
|
format!("Not a conversion type {:?}", c_type_val).into(),
|
||||||
val_pos,
|
val_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -356,14 +356,14 @@ impl Builtins {
|
|||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
stack.push((
|
stack.push((
|
||||||
Rc::new(P(Str(
|
Rc::new(P(Str(
|
||||||
String::from_utf8_lossy(buf.as_slice()).to_string()
|
String::from_utf8_lossy(buf.as_slice()).into()
|
||||||
))),
|
))),
|
||||||
pos,
|
pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Err(_e) => {
|
Err(_e) => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("No such conversion type {:?}", c_type),
|
format!("No such conversion type {:?}", c_type).into(),
|
||||||
c_typ_pos,
|
c_typ_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -373,7 +373,7 @@ impl Builtins {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Not a conversion type {:?}", val),
|
format!("Not a conversion type {:?}", val).into(),
|
||||||
val_pos,
|
val_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -384,7 +384,7 @@ impl Builtins {
|
|||||||
&self,
|
&self,
|
||||||
stack: &mut Vec<(Rc<Value>, Position)>,
|
stack: &mut Vec<(Rc<Value>, Position)>,
|
||||||
env: &'a RefCell<Environment<O, E>>,
|
env: &'a RefCell<Environment<O, E>>,
|
||||||
import_stack: &Vec<String>,
|
import_stack: &Vec<Rc<str>>,
|
||||||
pos: Position,
|
pos: Position,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
@ -407,7 +407,7 @@ impl Builtins {
|
|||||||
let f = if let &F(ref f) = fptr.as_ref() {
|
let f = if let &F(ref f) = fptr.as_ref() {
|
||||||
f
|
f
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(format!("Not a function!!"), fptr_pos));
|
return Err(Error::new(format!("Not a function!!").into(), fptr_pos));
|
||||||
};
|
};
|
||||||
|
|
||||||
match list.as_ref() {
|
match list.as_ref() {
|
||||||
@ -443,16 +443,14 @@ impl Builtins {
|
|||||||
// we expect them to be a list of exactly 2 items.
|
// we expect them to be a list of exactly 2 items.
|
||||||
if fval.len() != 2 {
|
if fval.len() != 2 {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!(
|
"Map Functions over tuples must return a list of two items".into(),
|
||||||
"Map Functions over tuples must return a list of two items"
|
|
||||||
),
|
|
||||||
result_pos,
|
result_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let name = match fval[0].as_ref() {
|
let name = match fval[0].as_ref() {
|
||||||
&P(Str(ref name)) => name.clone(),
|
&P(Str(ref name)) => name.clone(),
|
||||||
_ => return Err(Error::new(
|
_ => return Err(Error::new(
|
||||||
format!("Map functions over tuples must return a String as the first list item"),
|
"Map functions over tuples must return a String as the first list item".into(),
|
||||||
result_pos,
|
result_pos,
|
||||||
)),
|
)),
|
||||||
};
|
};
|
||||||
@ -467,7 +465,7 @@ impl Builtins {
|
|||||||
&P(Str(ref s)) => {
|
&P(Str(ref s)) => {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
for c in s.chars() {
|
for c in s.chars() {
|
||||||
stack.push((Rc::new(P(Str(c.to_string()))), list_pos.clone()));
|
stack.push((Rc::new(P(Str(c.to_string().into()))), list_pos.clone()));
|
||||||
// call function and push it's result on the stack.
|
// call function and push it's result on the stack.
|
||||||
let (result, result_pos) = decorate_call!(pos =>
|
let (result, result_pos) = decorate_call!(pos =>
|
||||||
VM::fcall_impl(f, self.strict, stack, env.clone(), import_stack))?;
|
VM::fcall_impl(f, self.strict, stack, env.clone(), import_stack))?;
|
||||||
@ -475,16 +473,16 @@ impl Builtins {
|
|||||||
buf.push_str(s);
|
buf.push_str(s);
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Map functions over string should return strings"),
|
"Map functions over string should return strings".into(),
|
||||||
result_pos,
|
result_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stack.push((Rc::new(P(Str(buf))), pos));
|
stack.push((Rc::new(P(Str(buf.into()))), pos));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("You can only map over lists, tuples, or strings"),
|
"You can only map over lists, tuples, or strings".into(),
|
||||||
pos,
|
pos,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -496,7 +494,7 @@ impl Builtins {
|
|||||||
&self,
|
&self,
|
||||||
stack: &mut Vec<(Rc<Value>, Position)>,
|
stack: &mut Vec<(Rc<Value>, Position)>,
|
||||||
env: &'a RefCell<Environment<O, E>>,
|
env: &'a RefCell<Environment<O, E>>,
|
||||||
import_stack: &Vec<String>,
|
import_stack: &Vec<Rc<str>>,
|
||||||
pos: Position,
|
pos: Position,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
@ -519,7 +517,7 @@ impl Builtins {
|
|||||||
let f = if let &F(ref f) = fptr.as_ref() {
|
let f = if let &F(ref f) = fptr.as_ref() {
|
||||||
f
|
f
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(format!("Not a function!!"), fptr_pos));
|
return Err(Error::new("Not a function!!".into(), fptr_pos));
|
||||||
};
|
};
|
||||||
|
|
||||||
match list.as_ref() {
|
match list.as_ref() {
|
||||||
@ -578,7 +576,7 @@ impl Builtins {
|
|||||||
&P(Str(ref s)) => {
|
&P(Str(ref s)) => {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
for c in s.chars() {
|
for c in s.chars() {
|
||||||
stack.push((Rc::new(P(Str(c.to_string()))), list_pos.clone()));
|
stack.push((Rc::new(P(Str(c.to_string().into()))), list_pos.clone()));
|
||||||
// call function and push it's result on the stack.
|
// call function and push it's result on the stack.
|
||||||
let (condition, _) = decorate_call!(pos =>
|
let (condition, _) = decorate_call!(pos =>
|
||||||
VM::fcall_impl(f, self.strict, stack, env.clone(), import_stack))?;
|
VM::fcall_impl(f, self.strict, stack, env.clone(), import_stack))?;
|
||||||
@ -591,11 +589,11 @@ impl Builtins {
|
|||||||
_ => buf.push(c),
|
_ => buf.push(c),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stack.push((Rc::new(P(Str(buf))), pos));
|
stack.push((Rc::new(P(Str(buf.into()))), pos));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("You can only filter over lists, tuples, or strings"),
|
"You can only filter over lists, tuples, or strings".into(),
|
||||||
pos,
|
pos,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -610,7 +608,7 @@ impl Builtins {
|
|||||||
s.clone()
|
s.clone()
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Expected string bug got {:?}", val),
|
format!("Expected string bug got {:?}", val).into(),
|
||||||
val_pos,
|
val_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -624,7 +622,7 @@ impl Builtins {
|
|||||||
s.clone()
|
s.clone()
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Expected string bug got {:?}", val),
|
format!("Expected string bug got {:?}", val).into(),
|
||||||
val_pos,
|
val_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -642,7 +640,7 @@ impl Builtins {
|
|||||||
&self,
|
&self,
|
||||||
stack: &mut Vec<(Rc<Value>, Position)>,
|
stack: &mut Vec<(Rc<Value>, Position)>,
|
||||||
env: &'a RefCell<Environment<O, E>>,
|
env: &'a RefCell<Environment<O, E>>,
|
||||||
import_stack: &Vec<String>,
|
import_stack: &Vec<Rc<str>>,
|
||||||
pos: Position,
|
pos: Position,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
@ -671,7 +669,7 @@ impl Builtins {
|
|||||||
let f = if let &F(ref f) = fptr.as_ref() {
|
let f = if let &F(ref f) = fptr.as_ref() {
|
||||||
f
|
f
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(format!("Not a function!"), fptr_pos));
|
return Err(Error::new("Noe a function!".into(), fptr_pos));
|
||||||
};
|
};
|
||||||
|
|
||||||
match list.as_ref() {
|
match list.as_ref() {
|
||||||
@ -711,7 +709,7 @@ impl Builtins {
|
|||||||
for c in s.chars() {
|
for c in s.chars() {
|
||||||
// push function arguments on the stack.
|
// push function arguments on the stack.
|
||||||
stack.push((acc.clone(), acc_pos.clone()));
|
stack.push((acc.clone(), acc_pos.clone()));
|
||||||
stack.push((Rc::new(P(Str(c.to_string()))), list_pos.clone()));
|
stack.push((Rc::new(P(Str(c.to_string().into()))), list_pos.clone()));
|
||||||
// call function and push it's result on the stack.
|
// call function and push it's result on the stack.
|
||||||
let (new_acc, new_acc_pos) = decorate_call!(pos =>
|
let (new_acc, new_acc_pos) = decorate_call!(pos =>
|
||||||
VM::fcall_impl(f, self.strict, stack, env.clone(), import_stack))?;
|
VM::fcall_impl(f, self.strict, stack, env.clone(), import_stack))?;
|
||||||
@ -721,7 +719,7 @@ impl Builtins {
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("You can only reduce over lists, tuples, or strings"),
|
"You can only reduce over lists, tuples, or strings".into(),
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -769,7 +767,7 @@ impl Builtins {
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Ranges can only be created with Ints"),
|
format!("Ranges can only be created with Ints").into(),
|
||||||
pos,
|
pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -809,7 +807,7 @@ impl Builtins {
|
|||||||
writable_val,
|
writable_val,
|
||||||
&val_pos
|
&val_pos
|
||||||
) {
|
) {
|
||||||
return Err(Error::new(format!("{}", e), pos));
|
return Err(Error::new(format!("{}", e).into(), pos));
|
||||||
};
|
};
|
||||||
stack.push((val, val_pos));
|
stack.push((val, val_pos));
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -19,7 +19,7 @@ use crate::ast::Position;
|
|||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub struct Stack {
|
pub struct Stack {
|
||||||
curr: BTreeMap<String, (Rc<Value>, Position)>,
|
curr: BTreeMap<Rc<str>, (Rc<Value>, Position)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stack {
|
impl Stack {
|
||||||
@ -41,12 +41,12 @@ impl Stack {
|
|||||||
self.curr.get(name).is_some()
|
self.curr.get(name).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, name: String, val: Rc<Value>, pos: Position) {
|
pub fn add(&mut self, name: Rc<str>, val: Rc<Value>, pos: Position) {
|
||||||
self.curr.insert(name, (val, pos));
|
self.curr.insert(name, (val, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn symbol_list(&self) -> Vec<&String> {
|
pub fn symbol_list(&self) -> Vec<Rc<str>> {
|
||||||
self.curr.keys().collect()
|
self.curr.keys().cloned().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn snapshot(&self) -> Self {
|
pub fn snapshot(&self) -> Self {
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::ast::rewrite::Rewriter;
|
use crate::ast::rewrite::Rewriter;
|
||||||
use crate::ast::walk::Walker;
|
use crate::ast::walk::Walker;
|
||||||
@ -30,8 +31,8 @@ pub struct AST();
|
|||||||
pub struct OpsMap {
|
pub struct OpsMap {
|
||||||
pub ops: Vec<Op>,
|
pub ops: Vec<Op>,
|
||||||
pub pos: Vec<Position>,
|
pub pos: Vec<Position>,
|
||||||
pub shape_map: BTreeMap<String, Shape>,
|
pub shape_map: BTreeMap<Rc<str>, Shape>,
|
||||||
pub links: BTreeMap<String, Position>,
|
pub links: BTreeMap<Rc<str>, Position>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OpsMap {
|
impl OpsMap {
|
||||||
@ -51,7 +52,7 @@ impl OpsMap {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_link(&mut self, path: String, pos: Position) {
|
pub fn add_link(&mut self, path: Rc<str>, pos: Position) {
|
||||||
self.links.insert(path, pos);
|
self.links.insert(path, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,7 +228,7 @@ impl AST {
|
|||||||
kind: BinaryExprType::IS,
|
kind: BinaryExprType::IS,
|
||||||
right: Box::new(Expression::Simple(Value::Str(
|
right: Box::new(Expression::Simple(Value::Str(
|
||||||
PositionedItem::new(
|
PositionedItem::new(
|
||||||
"tuple".to_owned(),
|
"tuple".into(),
|
||||||
def.left.pos().clone(),
|
def.left.pos().clone(),
|
||||||
),
|
),
|
||||||
))),
|
))),
|
||||||
@ -321,7 +322,7 @@ impl AST {
|
|||||||
Expression::Fail(def) => {
|
Expression::Fail(def) => {
|
||||||
let msg_pos = def.message.pos().clone();
|
let msg_pos = def.message.pos().clone();
|
||||||
Self::translate_expr(*def.message, &mut ops, root);
|
Self::translate_expr(*def.message, &mut ops, root);
|
||||||
ops.push(Op::Val(Primitive::Str("UserDefined: ".to_owned())), msg_pos);
|
ops.push(Op::Val(Primitive::Str("UserDefined: ".into())), msg_pos);
|
||||||
ops.push(Op::Add, def.pos.clone());
|
ops.push(Op::Add, def.pos.clone());
|
||||||
ops.push(Op::Bang, def.pos);
|
ops.push(Op::Bang, def.pos);
|
||||||
}
|
}
|
||||||
@ -373,7 +374,7 @@ impl AST {
|
|||||||
// Add our item binding shadowing any binding that already
|
// Add our item binding shadowing any binding that already
|
||||||
// existed.
|
// existed.
|
||||||
let expr_pos = expr.pos().clone();
|
let expr_pos = expr.pos().clone();
|
||||||
ops.push(Op::Sym("item".to_owned()), expr.pos().clone());
|
ops.push(Op::Sym("item".into()), expr.pos().clone());
|
||||||
Self::translate_expr(*expr, &mut ops, root);
|
Self::translate_expr(*expr, &mut ops, root);
|
||||||
ops.push(Op::BindOver, expr_pos.clone());
|
ops.push(Op::BindOver, expr_pos.clone());
|
||||||
let mut elems = Vec::new();
|
let mut elems = Vec::new();
|
||||||
@ -531,7 +532,7 @@ impl AST {
|
|||||||
} else {
|
} else {
|
||||||
ops.push(
|
ops.push(
|
||||||
Op::Val(Primitive::Str(
|
Op::Val(Primitive::Str(
|
||||||
"Unhandled select case with no default".to_owned(),
|
"Unhandled select case with no default".into(),
|
||||||
)),
|
)),
|
||||||
default_pos,
|
default_pos,
|
||||||
);
|
);
|
||||||
@ -569,7 +570,7 @@ impl AST {
|
|||||||
let _ = printer.render_expr(&def.expr);
|
let _ = printer.render_expr(&def.expr);
|
||||||
}
|
}
|
||||||
let expr_pretty = String::from_utf8(buffer).unwrap();
|
let expr_pretty = String::from_utf8(buffer).unwrap();
|
||||||
ops.push(Op::Val(Primitive::Str(expr_pretty)), def.pos.clone());
|
ops.push(Op::Val(Primitive::Str(expr_pretty.into())), def.pos.clone());
|
||||||
Self::translate_expr(*def.expr, &mut ops, root);
|
Self::translate_expr(*def.expr, &mut ops, root);
|
||||||
ops.push(Op::Runtime(Hook::Trace(def.pos.clone())), def.pos);
|
ops.push(Op::Runtime(Hook::Trace(def.pos.clone())), def.pos);
|
||||||
}
|
}
|
||||||
@ -586,7 +587,8 @@ impl AST {
|
|||||||
) {
|
) {
|
||||||
match part {
|
match part {
|
||||||
TemplatePart::Str(s) => {
|
TemplatePart::Str(s) => {
|
||||||
ops.push(Op::Val(Primitive::Str(s.into_iter().collect())), pos);
|
let part: String = s.into_iter().map(|c| c.to_string()).collect();
|
||||||
|
ops.push(Op::Val(Primitive::Str(part.into())), pos);
|
||||||
}
|
}
|
||||||
TemplatePart::PlaceHolder(_idx) => {
|
TemplatePart::PlaceHolder(_idx) => {
|
||||||
if !place_holder {
|
if !place_holder {
|
||||||
|
@ -46,7 +46,7 @@ pub struct VM {
|
|||||||
working_dir: PathBuf,
|
working_dir: PathBuf,
|
||||||
stack: Vec<(Rc<Value>, Position)>,
|
stack: Vec<(Rc<Value>, Position)>,
|
||||||
symbols: Stack,
|
symbols: Stack,
|
||||||
import_stack: Vec<String>,
|
import_stack: Vec<Rc<str>>,
|
||||||
runtime: runtime::Builtins,
|
runtime: runtime::Builtins,
|
||||||
ops: OpPointer,
|
ops: OpPointer,
|
||||||
pub last: Option<(Rc<Value>, Position)>,
|
pub last: Option<(Rc<Value>, Position)>,
|
||||||
@ -82,7 +82,7 @@ impl VM {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_import_stack(mut self, imports: Vec<String>) -> Self {
|
pub fn with_import_stack(mut self, imports: Vec<Rc<str>>) -> Self {
|
||||||
self.import_stack = imports;
|
self.import_stack = imports;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -114,8 +114,8 @@ impl VM {
|
|||||||
let mut flds = Vec::new();
|
let mut flds = Vec::new();
|
||||||
let mut pos_list = Vec::new();
|
let mut pos_list = Vec::new();
|
||||||
for sym in self.symbols.symbol_list() {
|
for sym in self.symbols.symbol_list() {
|
||||||
if include_mod || sym != "mod" {
|
if include_mod || sym.as_ref() != "mod" {
|
||||||
let (val, pos) = self.symbols.get(sym).unwrap().clone();
|
let (val, pos) = self.symbols.get(sym.as_ref()).unwrap().clone();
|
||||||
pos_list.push((pos.clone(), pos.clone()));
|
pos_list.push((pos.clone(), pos.clone()));
|
||||||
flds.push((sym.clone(), val));
|
flds.push((sym.clone(), val));
|
||||||
}
|
}
|
||||||
@ -198,7 +198,7 @@ impl VM {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
if let Some(p) = self.ops.path.as_ref() {
|
if let Some(p) = self.ops.path.as_ref() {
|
||||||
self.import_stack.push(p.to_string_lossy().to_string());
|
self.import_stack.push(p.to_string_lossy().into());
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -207,7 +207,7 @@ impl VM {
|
|||||||
if let Value::P(ref p) = val {
|
if let Value::P(ref p) = val {
|
||||||
self.push(
|
self.push(
|
||||||
Rc::new(match t {
|
Rc::new(match t {
|
||||||
CastType::Str => Value::P(Primitive::Str(format!("{}", p))),
|
CastType::Str => Value::P(Primitive::Str(format!("{}", p).into())),
|
||||||
CastType::Int => Value::P(Primitive::Int(p.try_into()?)),
|
CastType::Int => Value::P(Primitive::Int(p.try_into()?)),
|
||||||
CastType::Float => Value::P(Primitive::Float(p.try_into()?)),
|
CastType::Float => Value::P(Primitive::Float(p.try_into()?)),
|
||||||
CastType::Bool => Value::P(Primitive::Bool(p.try_into()?)),
|
CastType::Bool => Value::P(Primitive::Bool(p.try_into()?)),
|
||||||
@ -236,15 +236,14 @@ impl VM {
|
|||||||
M(_) => "module",
|
M(_) => "module",
|
||||||
S(_) => "sym",
|
S(_) => "sym",
|
||||||
T(_) => "thunk",
|
T(_) => "thunk",
|
||||||
}
|
};
|
||||||
.to_owned();
|
self.push(Rc::new(P(Str(typ_name.into()))), pos)?;
|
||||||
self.push(Rc::new(P(Str(typ_name))), pos)?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_deref<O, E>(
|
fn op_deref<O, E>(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: String,
|
name: Rc<str>,
|
||||||
env: &RefCell<Environment<O, E>>,
|
env: &RefCell<Environment<O, E>>,
|
||||||
pos: &Position,
|
pos: &Position,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
@ -279,7 +278,7 @@ impl VM {
|
|||||||
format!(
|
format!(
|
||||||
"Not a boolean condition {:?} in && expression at {}",
|
"Not a boolean condition {:?} in && expression at {}",
|
||||||
cond, pos
|
cond, pos
|
||||||
),
|
).into(),
|
||||||
cond_pos.clone(),
|
cond_pos.clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -299,7 +298,7 @@ impl VM {
|
|||||||
format!(
|
format!(
|
||||||
"Not a boolean condition {:?} in || expression at {}!",
|
"Not a boolean condition {:?} in || expression at {}!",
|
||||||
cond, pos
|
cond, pos
|
||||||
),
|
).into(),
|
||||||
cond_pos.clone(),
|
cond_pos.clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -314,7 +313,7 @@ impl VM {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Expected boolean but got {:?}!", cond),
|
format!("Expected boolean but got {:?}!", cond).into(),
|
||||||
cond_pos.clone(),
|
cond_pos.clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -329,7 +328,7 @@ impl VM {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Expected boolean but got {:?}!", cond),
|
format!("Expected boolean but got {:?}!", cond).into(),
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -345,9 +344,9 @@ impl VM {
|
|||||||
let matched = match (field_name.as_ref(), search.as_ref()) {
|
let matched = match (field_name.as_ref(), search.as_ref()) {
|
||||||
(&S(ref fname), &P(Str(ref sname))) | (&S(ref fname), &S(ref sname)) => fname == sname,
|
(&S(ref fname), &P(Str(ref sname))) | (&S(ref fname), &S(ref sname)) => fname == sname,
|
||||||
(&S(ref fname), &P(Bool(b))) => {
|
(&S(ref fname), &P(Bool(b))) => {
|
||||||
if fname == "true" && b {
|
if fname.as_ref() == "true" && b {
|
||||||
true
|
true
|
||||||
} else if fname == "false" && !b {
|
} else if fname.as_ref() == "false" && !b {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@ -373,14 +372,14 @@ impl VM {
|
|||||||
(Some(ptr), flds.clone(), pos_list.clone())
|
(Some(ptr), flds.clone(), pos_list.clone())
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Expected tuple but got {:?}", tpl_val),
|
format!("Expected tuple but got {:?}", tpl_val).into(),
|
||||||
tpl_val_pos,
|
tpl_val_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Expected tuple but got {:?}", mod_val),
|
format!("Expected tuple but got {:?}", mod_val).into(),
|
||||||
mod_val_pos,
|
mod_val_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -392,7 +391,7 @@ impl VM {
|
|||||||
let pkg_ops = vec![
|
let pkg_ops = vec![
|
||||||
Op::InitList,
|
Op::InitList,
|
||||||
Op::Func(3),
|
Op::Func(3),
|
||||||
Op::Val(Str(path.to_string_lossy().to_string())),
|
Op::Val(Str(path.to_string_lossy().into())),
|
||||||
Op::Runtime(Hook::Import),
|
Op::Runtime(Hook::Import),
|
||||||
Op::Return,
|
Op::Return,
|
||||||
];
|
];
|
||||||
@ -434,13 +433,13 @@ impl VM {
|
|||||||
bindings.push(sym.clone());
|
bindings.push(sym.clone());
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Not an argument name {:?}", e),
|
format!("Not an argument name {:?}", e).into(),
|
||||||
args_pos,
|
args_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(format!("Fault!!! Bad Argument List"), args_pos));
|
return Err(Error::new("Fault!!! Bad Argument List".into(), args_pos));
|
||||||
}
|
}
|
||||||
let mut ops = self.ops.clone();
|
let mut ops = self.ops.clone();
|
||||||
ops.jump(idx)?;
|
ops.jump(idx)?;
|
||||||
@ -462,7 +461,7 @@ impl VM {
|
|||||||
strict: bool,
|
strict: bool,
|
||||||
stack: &mut Vec<(Rc<Value>, Position)>,
|
stack: &mut Vec<(Rc<Value>, Position)>,
|
||||||
env: &'a RefCell<Environment<O, E>>,
|
env: &'a RefCell<Environment<O, E>>,
|
||||||
import_stack: &Vec<String>,
|
import_stack: &Vec<Rc<str>>,
|
||||||
) -> Result<(Rc<Value>, Position), Error>
|
) -> Result<(Rc<Value>, Position), Error>
|
||||||
where
|
where
|
||||||
O: std::io::Write + Clone,
|
O: std::io::Write + Clone,
|
||||||
@ -531,7 +530,7 @@ impl VM {
|
|||||||
format!(
|
format!(
|
||||||
"Func called with too many args expected {} args but got {}",
|
"Func called with too many args expected {} args but got {}",
|
||||||
arity, arg_length
|
arity, arg_length
|
||||||
),
|
).into(),
|
||||||
pos,
|
pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -540,7 +539,7 @@ impl VM {
|
|||||||
format!(
|
format!(
|
||||||
"Func called with too few args expected {} args but got {}",
|
"Func called with too few args expected {} args but got {}",
|
||||||
arity, arg_length
|
arity, arg_length
|
||||||
),
|
).into(),
|
||||||
pos,
|
pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -549,7 +548,7 @@ impl VM {
|
|||||||
Self::fcall_impl(f, self.runtime.strict, &mut self.stack, env.clone(), &self.import_stack))?;
|
Self::fcall_impl(f, self.runtime.strict, &mut self.stack, env.clone(), &self.import_stack))?;
|
||||||
self.push(val, pos.clone())?;
|
self.push(val, pos.clone())?;
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(format!("Not a function! {:?}", f,), pos));
|
return Err(Error::new(format!("Not a function! {:?}", f,).into(), pos));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -569,7 +568,7 @@ impl VM {
|
|||||||
format!(
|
format!(
|
||||||
"Expected Boolean but got {:?} in expression at {}",
|
"Expected Boolean but got {:?} in expression at {}",
|
||||||
operand, pos
|
operand, pos
|
||||||
),
|
).into(),
|
||||||
operand_pos,
|
operand_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -584,7 +583,7 @@ impl VM {
|
|||||||
format!(
|
format!(
|
||||||
"Expected values of the same type but got {:?} at {} and {:?} at {} for expression",
|
"Expected values of the same type but got {:?} at {} and {:?} at {} for expression",
|
||||||
left, left_pos, right, right_pos,
|
left, left_pos, right, right_pos,
|
||||||
),
|
).into(),
|
||||||
pos,
|
pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -607,7 +606,7 @@ impl VM {
|
|||||||
format!(
|
format!(
|
||||||
"Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression",
|
"Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression",
|
||||||
left, left_pos, right, right_pos,
|
left, left_pos, right, right_pos,
|
||||||
),
|
).into(),
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -630,7 +629,7 @@ impl VM {
|
|||||||
format!(
|
format!(
|
||||||
"Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression",
|
"Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression",
|
||||||
left, left_pos, right, right_pos,
|
left, left_pos, right, right_pos,
|
||||||
),
|
).into(),
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -653,7 +652,7 @@ impl VM {
|
|||||||
format!(
|
format!(
|
||||||
"Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression",
|
"Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression",
|
||||||
left, left_pos, right, right_pos,
|
left, left_pos, right, right_pos,
|
||||||
),
|
).into(),
|
||||||
pos,
|
pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -676,7 +675,7 @@ impl VM {
|
|||||||
format!(
|
format!(
|
||||||
"Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression",
|
"Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression",
|
||||||
left, left_pos, right, right_pos,
|
left, left_pos, right, right_pos,
|
||||||
),
|
).into(),
|
||||||
pos,
|
pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -850,7 +849,7 @@ impl VM {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Invalid selector index: {:?} target: {:?}", right, left),
|
format!("Invalid selector index: {:?} target: {:?}", right, left).into(),
|
||||||
pos,
|
pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -869,7 +868,7 @@ impl VM {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Expected String or Symbol got: {}", right.type_name()),
|
format!("Expected String or Symbol got: {}", right.type_name()).into(),
|
||||||
right_pos,
|
right_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -884,13 +883,13 @@ impl VM {
|
|||||||
}
|
}
|
||||||
&P(Str(ref s)) => {
|
&P(Str(ref s)) => {
|
||||||
if let &P(Str(ref part)) = right.as_ref() {
|
if let &P(Str(ref part)) = right.as_ref() {
|
||||||
self.push(Rc::new(P(Bool(s.contains(part)))), pos)?;
|
self.push(Rc::new(P(Bool(s.contains(part.as_ref())))), pos)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Expected String, Tuple, or List got: {}", left.type_name()),
|
format!("Expected String, Tuple, or List got: {}", left.type_name()).into(),
|
||||||
left_pos,
|
left_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -974,7 +973,7 @@ impl VM {
|
|||||||
self.merge_field_into_tuple(
|
self.merge_field_into_tuple(
|
||||||
&mut flds,
|
&mut flds,
|
||||||
&mut flds_pos_list,
|
&mut flds_pos_list,
|
||||||
"this".to_owned(),
|
"this".into(),
|
||||||
&pos,
|
&pos,
|
||||||
Rc::new(this),
|
Rc::new(this),
|
||||||
&val_pos,
|
&val_pos,
|
||||||
@ -989,7 +988,7 @@ impl VM {
|
|||||||
self.merge_field_into_tuple(
|
self.merge_field_into_tuple(
|
||||||
&mut flds,
|
&mut flds,
|
||||||
&mut flds_pos_list,
|
&mut flds_pos_list,
|
||||||
"pkg".to_owned(),
|
"pkg".into(),
|
||||||
&pos,
|
&pos,
|
||||||
pkg_func,
|
pkg_func,
|
||||||
&val_pos,
|
&val_pos,
|
||||||
@ -1000,7 +999,7 @@ impl VM {
|
|||||||
.clean_copy()
|
.clean_copy()
|
||||||
.to_new_pointer(ptr.clone())
|
.to_new_pointer(ptr.clone())
|
||||||
.with_import_stack(self.import_stack.clone());
|
.with_import_stack(self.import_stack.clone());
|
||||||
vm.push(Rc::new(S("mod".to_owned())), pos.clone())?;
|
vm.push(Rc::new(S("mod".into())), pos.clone())?;
|
||||||
vm.push(Rc::new(C(Tuple(flds, flds_pos_list))), pos.clone())?;
|
vm.push(Rc::new(C(Tuple(flds, flds_pos_list))), pos.clone())?;
|
||||||
decorate_call!(pos => vm.run(env))?;
|
decorate_call!(pos => vm.run(env))?;
|
||||||
if let Some(ptr) = result_ptr {
|
if let Some(ptr) = result_ptr {
|
||||||
@ -1014,7 +1013,7 @@ impl VM {
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Expected a Tuple or Module but got {:?}", tgt),
|
format!("Expected a Tuple or Module but got {:?}", tgt).into(),
|
||||||
pos,
|
pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -1024,9 +1023,9 @@ impl VM {
|
|||||||
|
|
||||||
fn merge_field_into_tuple(
|
fn merge_field_into_tuple(
|
||||||
&self,
|
&self,
|
||||||
src_fields: &mut Vec<(String, Rc<Value>)>,
|
src_fields: &mut Vec<(Rc<str>, Rc<Value>)>,
|
||||||
pos_fields: &mut Vec<(Position, Position)>,
|
pos_fields: &mut Vec<(Position, Position)>,
|
||||||
name: String,
|
name: Rc<str>,
|
||||||
name_pos: &Position,
|
name_pos: &Position,
|
||||||
value: Rc<Value>,
|
value: Rc<Value>,
|
||||||
val_pos: &Position,
|
val_pos: &Position,
|
||||||
@ -1043,7 +1042,7 @@ impl VM {
|
|||||||
fld.1.type_name(),
|
fld.1.type_name(),
|
||||||
name,
|
name,
|
||||||
value.type_name(),
|
value.type_name(),
|
||||||
),
|
).into(),
|
||||||
val_pos.clone(),
|
val_pos.clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -1065,21 +1064,21 @@ impl VM {
|
|||||||
|
|
||||||
pub fn binding_push(
|
pub fn binding_push(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: String,
|
name: Rc<str>,
|
||||||
val: Rc<Value>,
|
val: Rc<Value>,
|
||||||
strict: bool,
|
strict: bool,
|
||||||
pos: &Position,
|
pos: &Position,
|
||||||
name_pos: &Position,
|
name_pos: &Position,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
if self.reserved_words.contains(name.as_str()) {
|
if self.reserved_words.contains(name.as_ref()) {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("{} is a reserved word.", name),
|
format!("{} is a reserved word.", name).into(),
|
||||||
name_pos.clone(),
|
name_pos.clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if self.symbols.is_bound(&name) && strict {
|
if self.symbols.is_bound(&name) && strict {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Binding {} already exists", name),
|
format!("Binding {} already exists", name).into(),
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -1116,7 +1115,7 @@ impl VM {
|
|||||||
match tpl {
|
match tpl {
|
||||||
Some((v, pos)) => Ok((v, pos)),
|
Some((v, pos)) => Ok((v, pos)),
|
||||||
None => {
|
None => {
|
||||||
return Err(Error::new(format!("No such binding {}", name), pos.clone()));
|
return Err(Error::new(format!("No such binding {}", name).into(), pos.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1137,7 +1136,7 @@ impl VM {
|
|||||||
(P(Float(f)), P(Float(ff))) => Float(f * ff),
|
(P(Float(f)), P(Float(ff))) => Float(f * ff),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Expected {} but got {:?}", left.type_name(), right),
|
format!("Expected {} but got {:?}", left.type_name(), right).into(),
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -1150,7 +1149,7 @@ impl VM {
|
|||||||
(P(Float(f)), P(Float(ff))) => Float(f / ff),
|
(P(Float(f)), P(Float(ff))) => Float(f / ff),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Expected {} but got {:?}", left.type_name(), right),
|
format!("Expected {} but got {:?}", left.type_name(), right).into(),
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -1163,7 +1162,7 @@ impl VM {
|
|||||||
(P(Float(f)), Value::P(Float(ff))) => Float(f - ff),
|
(P(Float(f)), Value::P(Float(ff))) => Float(f - ff),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Expected {} but got {:?}", left.type_name(), right),
|
format!("Expected {} but got {:?}", left.type_name(), right).into(),
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -1176,7 +1175,7 @@ impl VM {
|
|||||||
(P(Float(f)), Value::P(Float(ff))) => Float(f % ff),
|
(P(Float(f)), Value::P(Float(ff))) => Float(f % ff),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Expected {} but got {:?}", left.type_name(), right),
|
format!("Expected {} but got {:?}", left.type_name(), right).into(),
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -1191,7 +1190,7 @@ impl VM {
|
|||||||
let mut ns = String::new();
|
let mut ns = String::new();
|
||||||
ns.push_str(&s);
|
ns.push_str(&s);
|
||||||
ns.push_str(&ss);
|
ns.push_str(&ss);
|
||||||
P(Str(ns))
|
P(Str(ns.into()))
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
C(List(ref left_list, ref left_pos_list)),
|
C(List(ref left_list, ref left_pos_list)),
|
||||||
@ -1216,7 +1215,7 @@ impl VM {
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
format!("Expected {} but got {:?}", left.type_name(), right),
|
format!("Expected {} but got {:?}", left.type_name(), right).into(),
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,9 @@ use crate::ast::PositionedItem;
|
|||||||
use crate::build::ir::Val;
|
use crate::build::ir::Val;
|
||||||
use crate::error;
|
use crate::error;
|
||||||
|
|
||||||
pub fn find_in_fieldlist(target: &str, fs: &Vec<(String, Rc<Val>)>) -> Option<Rc<Val>> {
|
pub fn find_in_fieldlist(target: &str, fs: &Vec<(Rc<str>, Rc<Val>)>) -> Option<Rc<Val>> {
|
||||||
for (key, val) in fs.iter().cloned() {
|
for (key, val) in fs.iter().cloned() {
|
||||||
if target == &key {
|
if target == key.as_ref() {
|
||||||
return Some(val.clone());
|
return Some(val.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -20,7 +20,7 @@ pub fn find_in_fieldlist(target: &str, fs: &Vec<(String, Rc<Val>)>) -> Option<Rc
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Defines a set of values in a parsed file.
|
/// Defines a set of values in a parsed file.
|
||||||
pub type ValueMap = HashMap<PositionedItem<String>, Rc<Val>>;
|
pub type ValueMap = HashMap<PositionedItem<Rc<str>>, Rc<Val>>;
|
||||||
|
|
||||||
/// Defines a scope for execution in ucg.
|
/// Defines a scope for execution in ucg.
|
||||||
///
|
///
|
||||||
@ -132,11 +132,11 @@ impl Scope {
|
|||||||
/// valid when the current value is a tuple.
|
/// valid when the current value is a tuple.
|
||||||
/// * everything else is looked up in the currently accumulated build output
|
/// * everything else is looked up in the currently accumulated build output
|
||||||
/// for this execution context.
|
/// for this execution context.
|
||||||
pub fn lookup_sym(&self, sym: &PositionedItem<String>, is_symbol: bool) -> Option<Rc<Val>> {
|
pub fn lookup_sym(&self, sym: &PositionedItem<Rc<str>>, is_symbol: bool) -> Option<Rc<Val>> {
|
||||||
if &sym.val == "env" && is_symbol {
|
if sym.val.as_ref() == "env" && is_symbol {
|
||||||
return Some(self.env.clone());
|
return Some(self.env.clone());
|
||||||
}
|
}
|
||||||
if &sym.val == "self" && is_symbol {
|
if sym.val.as_ref() == "self" && is_symbol {
|
||||||
return self.curr_val.clone();
|
return self.curr_val.clone();
|
||||||
}
|
}
|
||||||
if self.search_curr_val && self.curr_val.is_some() {
|
if self.search_curr_val && self.curr_val.is_some() {
|
||||||
@ -179,7 +179,7 @@ impl Scope {
|
|||||||
fn lookup_in_tuple(
|
fn lookup_in_tuple(
|
||||||
pos: &Position,
|
pos: &Position,
|
||||||
field: &str,
|
field: &str,
|
||||||
fs: &Vec<(String, Rc<Val>)>,
|
fs: &Vec<(Rc<str>, Rc<Val>)>,
|
||||||
) -> Result<Rc<Val>, Box<dyn Error>> {
|
) -> Result<Rc<Val>, Box<dyn Error>> {
|
||||||
if let Some(vv) = find_in_fieldlist(&field, fs) {
|
if let Some(vv) = find_in_fieldlist(&field, fs) {
|
||||||
Ok(vv)
|
Ok(vv)
|
||||||
|
@ -153,7 +153,7 @@ fn test_expr_copy_no_such_tuple() {
|
|||||||
vec![(
|
vec![(
|
||||||
Expression::Copy(CopyDef {
|
Expression::Copy(CopyDef {
|
||||||
selector: Value::Symbol(PositionedItem::new(
|
selector: Value::Symbol(PositionedItem::new(
|
||||||
"tpl1".to_string(),
|
"tpl1".into(),
|
||||||
Position::new(1, 1, 1),
|
Position::new(1, 1, 1),
|
||||||
)),
|
)),
|
||||||
fields: Vec::new(),
|
fields: Vec::new(),
|
||||||
|
@ -15,9 +15,9 @@ pub struct Base64Importer {
|
|||||||
impl Importer for Base64Importer {
|
impl Importer for Base64Importer {
|
||||||
fn import(&self, bytes: &[u8]) -> Result<Rc<Val>, Box<dyn Error>> {
|
fn import(&self, bytes: &[u8]) -> Result<Rc<Val>, Box<dyn Error>> {
|
||||||
return if self.url_safe {
|
return if self.url_safe {
|
||||||
Ok(Rc::new(Val::Str(STANDARD.encode(bytes))))
|
Ok(Rc::new(Val::Str(STANDARD.encode(bytes).into())))
|
||||||
} else {
|
} else {
|
||||||
Ok(Rc::new(Val::Str(URL_SAFE.encode(bytes))))
|
Ok(Rc::new(Val::Str(URL_SAFE.encode(bytes).into())))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ impl EnvConverter {
|
|||||||
EnvConverter {}
|
EnvConverter {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_tuple(&self, flds: &Vec<(String, Rc<Val>)>, w: &mut dyn IOWrite) -> ConvertResult {
|
fn convert_tuple(&self, flds: &Vec<(Rc<str>, Rc<Val>)>, w: &mut dyn IOWrite) -> ConvertResult {
|
||||||
for &(ref name, ref val) in flds.iter() {
|
for &(ref name, ref val) in flds.iter() {
|
||||||
if val.is_tuple() {
|
if val.is_tuple() {
|
||||||
eprintln!("Skipping embedded tuple...");
|
eprintln!("Skipping embedded tuple...");
|
||||||
|
@ -48,12 +48,12 @@ impl ExecConverter {
|
|||||||
)
|
)
|
||||||
.to_boxed());
|
.to_boxed());
|
||||||
}
|
}
|
||||||
let mut env: Option<&Vec<(String, Rc<Val>)>> = None;
|
let mut env: Option<&Vec<(Rc<str>, Rc<Val>)>> = None;
|
||||||
let mut command: Option<&str> = None;
|
let mut command: Option<&str> = None;
|
||||||
let mut args: Option<&Vec<Rc<Val>>> = None;
|
let mut args: Option<&Vec<Rc<Val>>> = None;
|
||||||
for &(ref name, ref val) in fields.iter() {
|
for &(ref name, ref val) in fields.iter() {
|
||||||
// We require a command field in our exec tuple.
|
// We require a command field in our exec tuple.
|
||||||
if name == "command" {
|
if name.as_ref() == "command" {
|
||||||
if command.is_some() {
|
if command.is_some() {
|
||||||
return Err(BuildError::new(
|
return Err(BuildError::new(
|
||||||
"There can only be one command field in an exec tuple",
|
"There can only be one command field in an exec tuple",
|
||||||
@ -72,7 +72,7 @@ impl ExecConverter {
|
|||||||
.to_boxed());
|
.to_boxed());
|
||||||
}
|
}
|
||||||
// We optionally allow an env field in our exec tuple.
|
// We optionally allow an env field in our exec tuple.
|
||||||
if name == "env" {
|
if name.as_ref() == "env" {
|
||||||
if let &Val::Tuple(ref l) = val.as_ref() {
|
if let &Val::Tuple(ref l) = val.as_ref() {
|
||||||
if env.is_some() {
|
if env.is_some() {
|
||||||
return Err(BuildError::new(
|
return Err(BuildError::new(
|
||||||
@ -91,7 +91,7 @@ impl ExecConverter {
|
|||||||
.to_boxed());
|
.to_boxed());
|
||||||
}
|
}
|
||||||
// We optionally allow an args field in our exec tuple.
|
// We optionally allow an args field in our exec tuple.
|
||||||
if name == "args" {
|
if name.as_ref() == "args" {
|
||||||
if let &Val::List(ref l) = val.as_ref() {
|
if let &Val::List(ref l) = val.as_ref() {
|
||||||
if args.is_some() {
|
if args.is_some() {
|
||||||
return Err(BuildError::new(
|
return Err(BuildError::new(
|
||||||
|
@ -94,7 +94,7 @@ impl FlagConverter {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&self, pfx: &str, flds: &Vec<(String, Rc<Val>)>, w: &mut dyn Write) -> ConvertResult {
|
fn write(&self, pfx: &str, flds: &Vec<(Rc<str>, Rc<Val>)>, w: &mut dyn Write) -> ConvertResult {
|
||||||
for &(ref name, ref val) in flds.iter() {
|
for &(ref name, ref val) in flds.iter() {
|
||||||
if let &Val::Empty = val.as_ref() {
|
if let &Val::Empty = val.as_ref() {
|
||||||
self.write_flag_name(pfx, name, w)?;
|
self.write_flag_name(pfx, name, w)?;
|
||||||
|
@ -34,19 +34,19 @@ impl JsonConverter {
|
|||||||
Ok(serde_json::Value::Array(v))
|
Ok(serde_json::Value::Array(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_tuple(&self, items: &Vec<(String, Rc<Val>)>) -> std::io::Result<serde_json::Value> {
|
fn convert_tuple(&self, items: &Vec<(Rc<str>, Rc<Val>)>) -> std::io::Result<serde_json::Value> {
|
||||||
let mut mp = serde_json::Map::new();
|
let mut mp = serde_json::Map::new();
|
||||||
for &(ref k, ref v) in items.iter() {
|
for &(ref k, ref v) in items.iter() {
|
||||||
mp.entry(k.clone()).or_insert(self.convert_value(v)?);
|
mp.entry(k.as_ref()).or_insert(self.convert_value(v)?);
|
||||||
}
|
}
|
||||||
Ok(serde_json::Value::Object(mp))
|
Ok(serde_json::Value::Object(mp))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_env(&self, items: &Vec<(String, String)>) -> std::io::Result<serde_json::Value> {
|
fn convert_env(&self, items: &Vec<(Rc<str>, Rc<str>)>) -> std::io::Result<serde_json::Value> {
|
||||||
let mut mp = serde_json::Map::new();
|
let mut mp = serde_json::Map::new();
|
||||||
for &(ref k, ref v) in items.iter() {
|
for &(ref k, ref v) in items.iter() {
|
||||||
mp.entry(k.clone())
|
mp.entry(k.as_ref())
|
||||||
.or_insert(serde_json::Value::String(v.clone()));
|
.or_insert(serde_json::Value::String(v.to_string()));
|
||||||
}
|
}
|
||||||
Ok(serde_json::Value::Object(mp))
|
Ok(serde_json::Value::Object(mp))
|
||||||
}
|
}
|
||||||
@ -71,7 +71,7 @@ impl JsonConverter {
|
|||||||
};
|
};
|
||||||
serde_json::Value::Number(n)
|
serde_json::Value::Number(n)
|
||||||
}
|
}
|
||||||
&Val::Str(ref s) => serde_json::Value::String(s.clone()),
|
&Val::Str(ref s) => serde_json::Value::String(s.to_string()),
|
||||||
&Val::Env(ref fs) => self.convert_env(fs)?,
|
&Val::Env(ref fs) => self.convert_env(fs)?,
|
||||||
&Val::List(ref l) => self.convert_list(l)?,
|
&Val::List(ref l) => self.convert_list(l)?,
|
||||||
&Val::Tuple(ref t) => self.convert_tuple(t)?,
|
&Val::Tuple(ref t) => self.convert_tuple(t)?,
|
||||||
@ -81,7 +81,7 @@ impl JsonConverter {
|
|||||||
|
|
||||||
fn convert_json_val(&self, v: &serde_json::Value) -> std::result::Result<Val, Box<dyn Error>> {
|
fn convert_json_val(&self, v: &serde_json::Value) -> std::result::Result<Val, Box<dyn Error>> {
|
||||||
Ok(match v {
|
Ok(match v {
|
||||||
serde_json::Value::String(s) => Val::Str(s.clone()),
|
serde_json::Value::String(s) => Val::Str(s.clone().into()),
|
||||||
serde_json::Value::Number(n) => {
|
serde_json::Value::Number(n) => {
|
||||||
if let Some(i) = n.as_i64() {
|
if let Some(i) = n.as_i64() {
|
||||||
Val::Int(i)
|
Val::Int(i)
|
||||||
@ -101,7 +101,7 @@ impl JsonConverter {
|
|||||||
serde_json::Value::Object(m) => {
|
serde_json::Value::Object(m) => {
|
||||||
let mut fs = Vec::with_capacity(m.len());
|
let mut fs = Vec::with_capacity(m.len());
|
||||||
for (key, value) in m {
|
for (key, value) in m {
|
||||||
fs.push((key.to_string(), Rc::new(self.convert_json_val(value)?)));
|
fs.push((key.clone().into(), Rc::new(self.convert_json_val(value)?)));
|
||||||
}
|
}
|
||||||
Val::Tuple(fs)
|
Val::Tuple(fs)
|
||||||
}
|
}
|
||||||
|
@ -41,19 +41,19 @@ impl TomlConverter {
|
|||||||
Ok(toml::Value::Array(v))
|
Ok(toml::Value::Array(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_tuple(&self, items: &Vec<(String, Rc<Val>)>) -> Result {
|
fn convert_tuple(&self, items: &Vec<(Rc<str>, Rc<Val>)>) -> Result {
|
||||||
let mut mp = toml::value::Table::new();
|
let mut mp = toml::value::Table::new();
|
||||||
for &(ref k, ref v) in items.iter() {
|
for &(ref k, ref v) in items.iter() {
|
||||||
mp.entry(k.clone()).or_insert(self.convert_value(v)?);
|
mp.entry(k.to_string()).or_insert(self.convert_value(v)?);
|
||||||
}
|
}
|
||||||
Ok(toml::Value::Table(mp))
|
Ok(toml::Value::Table(mp))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_env(&self, items: &Vec<(String, String)>) -> Result {
|
fn convert_env(&self, items: &Vec<(Rc<str>, Rc<str>)>) -> Result {
|
||||||
let mut mp = toml::value::Table::new();
|
let mut mp = toml::value::Table::new();
|
||||||
for &(ref k, ref v) in items.iter() {
|
for &(ref k, ref v) in items.iter() {
|
||||||
mp.entry(k.clone())
|
mp.entry(k.to_string())
|
||||||
.or_insert(toml::Value::String(v.clone()));
|
.or_insert(toml::Value::String(v.to_string()));
|
||||||
}
|
}
|
||||||
Ok(toml::Value::Table(mp))
|
Ok(toml::Value::Table(mp))
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ impl TomlConverter {
|
|||||||
}
|
}
|
||||||
&Val::Float(f) => toml::Value::Float(f),
|
&Val::Float(f) => toml::Value::Float(f),
|
||||||
&Val::Int(i) => toml::Value::Integer(i),
|
&Val::Int(i) => toml::Value::Integer(i),
|
||||||
&Val::Str(ref s) => toml::Value::String(s.clone()),
|
&Val::Str(ref s) => toml::Value::String(s.to_string()),
|
||||||
&Val::Env(ref fs) => self.convert_env(fs)?,
|
&Val::Env(ref fs) => self.convert_env(fs)?,
|
||||||
&Val::List(ref l) => self.convert_list(l)?,
|
&Val::List(ref l) => self.convert_list(l)?,
|
||||||
&Val::Tuple(ref t) => self.convert_tuple(t)?,
|
&Val::Tuple(ref t) => self.convert_tuple(t)?,
|
||||||
@ -77,7 +77,7 @@ impl TomlConverter {
|
|||||||
|
|
||||||
fn convert_toml_val(&self, v: &toml::Value) -> std::result::Result<Val, Box<dyn Error>> {
|
fn convert_toml_val(&self, v: &toml::Value) -> std::result::Result<Val, Box<dyn Error>> {
|
||||||
Ok(match v {
|
Ok(match v {
|
||||||
toml::Value::String(s) => Val::Str(s.clone()),
|
toml::Value::String(s) => Val::Str(s.clone().into()),
|
||||||
toml::Value::Integer(i) => Val::Int(*i),
|
toml::Value::Integer(i) => Val::Int(*i),
|
||||||
toml::Value::Float(f) => Val::Float(*f),
|
toml::Value::Float(f) => Val::Float(*f),
|
||||||
toml::Value::Boolean(b) => Val::Boolean(*b),
|
toml::Value::Boolean(b) => Val::Boolean(*b),
|
||||||
@ -91,11 +91,11 @@ impl TomlConverter {
|
|||||||
toml::Value::Table(m) => {
|
toml::Value::Table(m) => {
|
||||||
let mut fs = Vec::with_capacity(m.len());
|
let mut fs = Vec::with_capacity(m.len());
|
||||||
for (key, value) in m {
|
for (key, value) in m {
|
||||||
fs.push((key.to_string(), Rc::new(self.convert_toml_val(value)?)));
|
fs.push((key.clone().into(), Rc::new(self.convert_toml_val(value)?)));
|
||||||
}
|
}
|
||||||
Val::Tuple(fs)
|
Val::Tuple(fs)
|
||||||
}
|
}
|
||||||
toml::Value::Datetime(d) => Val::Str(format!("{}", d)),
|
toml::Value::Datetime(d) => Val::Str(format!("{}", d).into()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ impl XmlConverter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_tuple_val(v: &Val) -> std::result::Result<&Vec<(String, Rc<Val>)>, Box<dyn Error>> {
|
fn get_tuple_val(v: &Val) -> std::result::Result<&Vec<(Rc<str>, Rc<Val>)>, Box<dyn Error>> {
|
||||||
if let Val::Tuple(ref fs) = v {
|
if let Val::Tuple(ref fs) = v {
|
||||||
Ok(fs)
|
Ok(fs)
|
||||||
} else {
|
} else {
|
||||||
@ -58,15 +58,15 @@ impl XmlConverter {
|
|||||||
// First we determine if this is a tag or text node
|
// First we determine if this is a tag or text node
|
||||||
if let Val::Tuple(ref fs) = v {
|
if let Val::Tuple(ref fs) = v {
|
||||||
let mut name: Option<&str> = None;
|
let mut name: Option<&str> = None;
|
||||||
let mut attrs: Option<&Vec<(String, Rc<Val>)>> = None;
|
let mut attrs: Option<&Vec<(Rc<str>, Rc<Val>)>> = None;
|
||||||
let mut children: Option<&Vec<Rc<Val>>> = None;
|
let mut children: Option<&Vec<Rc<Val>>> = None;
|
||||||
let mut text: Option<&str> = None;
|
let mut text: Option<&str> = None;
|
||||||
let mut ns: Option<(&str, &str)> = None;
|
let mut ns: Option<(&str, &str)> = None;
|
||||||
for (ref field, ref val) in fs.iter() {
|
for (ref field, ref val) in fs.iter() {
|
||||||
if field == "name" {
|
if field.as_ref() == "name" {
|
||||||
name = Some(Self::get_str_val(val.as_ref())?);
|
name = Some(Self::get_str_val(val.as_ref())?);
|
||||||
}
|
}
|
||||||
if field == "ns" {
|
if field.as_ref() == "ns" {
|
||||||
if let Val::Tuple(ref fs) = val.as_ref() {
|
if let Val::Tuple(ref fs) = val.as_ref() {
|
||||||
let mut prefix = "";
|
let mut prefix = "";
|
||||||
let mut uri = "";
|
let mut uri = "";
|
||||||
@ -74,10 +74,10 @@ impl XmlConverter {
|
|||||||
if val.is_empty() {
|
if val.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if name == "uri" {
|
if name.as_ref() == "uri" {
|
||||||
uri = Self::get_str_val(val.as_ref())?;
|
uri = Self::get_str_val(val.as_ref())?;
|
||||||
}
|
}
|
||||||
if name == "prefix" {
|
if name.as_ref() == "prefix" {
|
||||||
prefix = Self::get_str_val(val.as_ref())?;
|
prefix = Self::get_str_val(val.as_ref())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,19 +88,19 @@ impl XmlConverter {
|
|||||||
ns = Some(("", s));
|
ns = Some(("", s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if field == "attrs" {
|
if field.as_ref() == "attrs" {
|
||||||
// This should be a tuple.
|
// This should be a tuple.
|
||||||
if !val.is_empty() {
|
if !val.is_empty() {
|
||||||
attrs = Some(Self::get_tuple_val(val.as_ref())?);
|
attrs = Some(Self::get_tuple_val(val.as_ref())?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if field == "children" {
|
if field.as_ref() == "children" {
|
||||||
// This should be a list of tuples.
|
// This should be a list of tuples.
|
||||||
if !val.is_empty() {
|
if !val.is_empty() {
|
||||||
children = Some(Self::get_list_val(val.as_ref())?);
|
children = Some(Self::get_list_val(val.as_ref())?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if field == "text" {
|
if field.as_ref() == "text" {
|
||||||
if !val.is_empty() {
|
if !val.is_empty() {
|
||||||
text = Some(Self::get_str_val(val.as_ref())?);
|
text = Some(Self::get_str_val(val.as_ref())?);
|
||||||
}
|
}
|
||||||
@ -160,19 +160,19 @@ impl XmlConverter {
|
|||||||
let mut standalone: Option<bool> = None;
|
let mut standalone: Option<bool> = None;
|
||||||
let mut root: Option<Rc<Val>> = None;
|
let mut root: Option<Rc<Val>> = None;
|
||||||
for &(ref name, ref val) in fs.iter() {
|
for &(ref name, ref val) in fs.iter() {
|
||||||
if name == "version" {
|
if name.as_ref() == "version" {
|
||||||
version = Some(Self::get_str_val(val)?);
|
version = Some(Self::get_str_val(val)?);
|
||||||
}
|
}
|
||||||
if name == "encoding" {
|
if name.as_ref() == "encoding" {
|
||||||
encoding = Some(Self::get_str_val(val)?);
|
encoding = Some(Self::get_str_val(val)?);
|
||||||
}
|
}
|
||||||
if name == "standalone" {
|
if name.as_ref() == "standalone" {
|
||||||
standalone = match val.as_ref() {
|
standalone = match val.as_ref() {
|
||||||
Val::Boolean(b) => Some(*b),
|
Val::Boolean(b) => Some(*b),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if name == "root" {
|
if name.as_ref() == "root" {
|
||||||
root = Some(val.clone());
|
root = Some(val.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,21 +25,21 @@ impl YamlConverter {
|
|||||||
Ok(serde_yaml::Value::Sequence(v))
|
Ok(serde_yaml::Value::Sequence(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_env(&self, items: &Vec<(String, String)>) -> std::io::Result<serde_yaml::Value> {
|
fn convert_env(&self, items: &Vec<(Rc<str>, Rc<str>)>) -> std::io::Result<serde_yaml::Value> {
|
||||||
let mut mp = serde_yaml::Mapping::new();
|
let mut mp = serde_yaml::Mapping::new();
|
||||||
for &(ref k, ref v) in items.iter() {
|
for &(ref k, ref v) in items.iter() {
|
||||||
mp.insert(
|
mp.insert(
|
||||||
serde_yaml::Value::String(k.clone()),
|
serde_yaml::Value::String(k.to_string()),
|
||||||
serde_yaml::Value::String(v.clone()),
|
serde_yaml::Value::String(v.to_string()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok(serde_yaml::Value::Mapping(mp))
|
Ok(serde_yaml::Value::Mapping(mp))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_tuple(&self, items: &Vec<(String, Rc<Val>)>) -> std::io::Result<serde_yaml::Value> {
|
fn convert_tuple(&self, items: &Vec<(Rc<str>, Rc<Val>)>) -> std::io::Result<serde_yaml::Value> {
|
||||||
let mut mapping = serde_yaml::Mapping::new();
|
let mut mapping = serde_yaml::Mapping::new();
|
||||||
for &(ref k, ref v) in items.iter() {
|
for &(ref k, ref v) in items.iter() {
|
||||||
mapping.insert(serde_yaml::Value::String(k.clone()), self.convert_value(v)?);
|
mapping.insert(serde_yaml::Value::String(k.to_string()), self.convert_value(v)?);
|
||||||
}
|
}
|
||||||
Ok(serde_yaml::Value::Mapping(mapping))
|
Ok(serde_yaml::Value::Mapping(mapping))
|
||||||
}
|
}
|
||||||
@ -56,7 +56,7 @@ impl YamlConverter {
|
|||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
_ => panic!("Int is too large or not a Number {}", i),
|
_ => panic!("Int is too large or not a Number {}", i),
|
||||||
},
|
},
|
||||||
&Val::Str(ref s) => serde_yaml::Value::String(s.clone()),
|
&Val::Str(ref s) => serde_yaml::Value::String(s.to_string()),
|
||||||
&Val::Env(ref fs) => self.convert_env(fs)?,
|
&Val::Env(ref fs) => self.convert_env(fs)?,
|
||||||
&Val::List(ref l) => self.convert_list(l)?,
|
&Val::List(ref l) => self.convert_list(l)?,
|
||||||
&Val::Tuple(ref t) => self.convert_tuple(t)?,
|
&Val::Tuple(ref t) => self.convert_tuple(t)?,
|
||||||
@ -97,7 +97,7 @@ impl YamlConverter {
|
|||||||
|
|
||||||
fn convert_yaml_val(&self, v: &serde_yaml::Value) -> Result<Val, Box<dyn Error>> {
|
fn convert_yaml_val(&self, v: &serde_yaml::Value) -> Result<Val, Box<dyn Error>> {
|
||||||
Ok(match v {
|
Ok(match v {
|
||||||
serde_yaml::Value::String(s) => Val::Str(s.clone()),
|
serde_yaml::Value::String(s) => Val::Str(s.clone().into()),
|
||||||
serde_yaml::Value::Number(n) => {
|
serde_yaml::Value::Number(n) => {
|
||||||
if let Some(i) = n.as_i64() {
|
if let Some(i) = n.as_i64() {
|
||||||
Val::Int(i)
|
Val::Int(i)
|
||||||
@ -122,7 +122,7 @@ impl YamlConverter {
|
|||||||
let mut collapsed = Vec::with_capacity(fs.len());
|
let mut collapsed = Vec::with_capacity(fs.len());
|
||||||
for (k, val) in fs {
|
for (k, val) in fs {
|
||||||
if !seen_keys.contains(&k) {
|
if !seen_keys.contains(&k) {
|
||||||
collapsed.push((k.clone(), val));
|
collapsed.push((k.clone().into(), val));
|
||||||
seen_keys.insert(k);
|
seen_keys.insert(k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -489,7 +489,7 @@ fn main() {
|
|||||||
let mut import_paths = Vec::new();
|
let mut import_paths = Vec::new();
|
||||||
let mut env_vars = BTreeMap::new();
|
let mut env_vars = BTreeMap::new();
|
||||||
for (var, val) in std::env::vars() {
|
for (var, val) in std::env::vars() {
|
||||||
env_vars.insert(var, val);
|
env_vars.insert(var.into(), val.into());
|
||||||
}
|
}
|
||||||
let env = RefCell::new(Environment::new_with_vars(
|
let env = RefCell::new(Environment::new_with_vars(
|
||||||
StdoutWrapper::new(),
|
StdoutWrapper::new(),
|
||||||
|
@ -71,7 +71,7 @@ macro_rules! trace_parse {
|
|||||||
|
|
||||||
fn symbol_to_value(s: &Token) -> ConvertResult<Value> {
|
fn symbol_to_value(s: &Token) -> ConvertResult<Value> {
|
||||||
Ok(Value::Symbol(value_node!(
|
Ok(Value::Symbol(value_node!(
|
||||||
s.fragment.to_string(),
|
s.fragment.clone(),
|
||||||
s.pos.clone()
|
s.pos.clone()
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ make_fn!(
|
|||||||
|
|
||||||
fn str_to_value(s: &Token) -> ConvertResult<Value> {
|
fn str_to_value(s: &Token) -> ConvertResult<Value> {
|
||||||
Ok(Value::Str(value_node!(
|
Ok(Value::Str(value_node!(
|
||||||
s.fragment.to_string(),
|
s.fragment.clone(),
|
||||||
s.pos.clone()
|
s.pos.clone()
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
@ -125,7 +125,7 @@ fn triple_to_number<'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let suf = match v.2 {
|
let suf = match v.2 {
|
||||||
None => "".to_string(),
|
None => "".into(),
|
||||||
Some(bs) => bs.fragment,
|
Some(bs) => bs.fragment,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -205,7 +205,7 @@ make_fn!(
|
|||||||
do_each!(
|
do_each!(
|
||||||
b => match_type!(BOOLEAN),
|
b => match_type!(BOOLEAN),
|
||||||
(Value::Boolean(PositionedItem{
|
(Value::Boolean(PositionedItem{
|
||||||
val: b.fragment == "true",
|
val: b.fragment.as_ref() == "true",
|
||||||
pos: b.pos,
|
pos: b.pos,
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
@ -367,7 +367,7 @@ fn tuple_to_func<'a>(
|
|||||||
.drain(0..)
|
.drain(0..)
|
||||||
.map(|s| PositionedItem {
|
.map(|s| PositionedItem {
|
||||||
pos: s.pos().clone(),
|
pos: s.pos().clone(),
|
||||||
val: s.to_string(),
|
val: s.to_string().into(),
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
Ok(Expression::Func(FuncDef {
|
Ok(Expression::Func(FuncDef {
|
||||||
@ -567,7 +567,7 @@ make_fn!(
|
|||||||
expr => expression,
|
expr => expression,
|
||||||
_ => punct!(")"),
|
_ => punct!(")"),
|
||||||
(Expression::Cast(CastDef{
|
(Expression::Cast(CastDef{
|
||||||
cast_type: match typ.fragment.as_str() {
|
cast_type: match typ.fragment.as_ref() {
|
||||||
"int" => CastType::Int,
|
"int" => CastType::Int,
|
||||||
"float" => CastType::Float,
|
"float" => CastType::Float,
|
||||||
"str" => CastType::Str,
|
"str" => CastType::Str,
|
||||||
@ -812,7 +812,7 @@ macro_rules! match_binding_name {
|
|||||||
let mut _i = $i.clone();
|
let mut _i = $i.clone();
|
||||||
match match_type!(_i, BAREWORD) {
|
match match_type!(_i, BAREWORD) {
|
||||||
Result::Complete(i, t) => {
|
Result::Complete(i, t) => {
|
||||||
if t.fragment == "env" {
|
if t.fragment.as_ref() == "env" {
|
||||||
return Result::Abort(Error::new(
|
return Result::Abort(Error::new(
|
||||||
format!("Cannot use binding {}. It is a reserved word.", t.fragment),
|
format!("Cannot use binding {}. It is a reserved word.", t.fragment),
|
||||||
Box::new($i.clone()),
|
Box::new($i.clone()),
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
//! The tokenization stage of the ucg compiler.
|
//! The tokenization stage of the ucg compiler.
|
||||||
use std;
|
use std;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use abortable_parser::combinators::*;
|
use abortable_parser::combinators::*;
|
||||||
use abortable_parser::iter::SliceIter;
|
use abortable_parser::iter::SliceIter;
|
||||||
@ -104,7 +105,7 @@ make_fn!(strtok<OffsetStrIter, Token>,
|
|||||||
(Token{
|
(Token{
|
||||||
typ: TokenType::QUOTED,
|
typ: TokenType::QUOTED,
|
||||||
pos: Position::from(&span),
|
pos: Position::from(&span),
|
||||||
fragment: frag.to_string(),
|
fragment: frag.into(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -117,7 +118,7 @@ make_fn!(barewordtok<OffsetStrIter, Token>,
|
|||||||
(Token{
|
(Token{
|
||||||
typ: TokenType::BAREWORD,
|
typ: TokenType::BAREWORD,
|
||||||
pos: Position::from(&span),
|
pos: Position::from(&span),
|
||||||
fragment: frag.to_string(),
|
fragment: frag.into(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -130,7 +131,7 @@ make_fn!(digittok<OffsetStrIter, Token>,
|
|||||||
(Token{
|
(Token{
|
||||||
typ: TokenType::DIGIT,
|
typ: TokenType::DIGIT,
|
||||||
pos: Position::from(&span),
|
pos: Position::from(&span),
|
||||||
fragment: digits.to_string(),
|
fragment: digits.into(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -145,7 +146,7 @@ make_fn!(booleantok<OffsetStrIter, Token>,
|
|||||||
(Token{
|
(Token{
|
||||||
typ: TokenType::BOOLEAN,
|
typ: TokenType::BOOLEAN,
|
||||||
pos: Position::from(&span),
|
pos: Position::from(&span),
|
||||||
fragment: token.to_string(),
|
fragment: token.into(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -161,7 +162,7 @@ macro_rules! do_text_token_tok {
|
|||||||
(Token {
|
(Token {
|
||||||
typ: $type,
|
typ: $type,
|
||||||
pos: Position::from(&span),
|
pos: Position::from(&span),
|
||||||
fragment: frag.to_string(),
|
fragment: frag.into(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
@ -173,7 +174,7 @@ macro_rules! do_text_token_tok {
|
|||||||
(Token {
|
(Token {
|
||||||
typ: $type,
|
typ: $type,
|
||||||
pos: Position::from(&span),
|
pos: Position::from(&span),
|
||||||
fragment: frag.to_string(),
|
fragment: frag.into(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
@ -414,7 +415,7 @@ make_fn!(whitespace<OffsetStrIter, Token>,
|
|||||||
(Token{
|
(Token{
|
||||||
typ: TokenType::WS,
|
typ: TokenType::WS,
|
||||||
pos: Position::from(&span),
|
pos: Position::from(&span),
|
||||||
fragment: String::new(),
|
fragment: "".into(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -426,7 +427,7 @@ make_fn!(end_of_input<OffsetStrIter, Token>,
|
|||||||
(Token{
|
(Token{
|
||||||
typ: TokenType::END,
|
typ: TokenType::END,
|
||||||
pos: Position::from(&span),
|
pos: Position::from(&span),
|
||||||
fragment: String::new(),
|
fragment: "".into(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -557,7 +558,7 @@ pub fn tokenize<'a>(
|
|||||||
}
|
}
|
||||||
// ensure that we always have an END token to go off of.
|
// ensure that we always have an END token to go off of.
|
||||||
out.push(Token {
|
out.push(Token {
|
||||||
fragment: String::new(),
|
fragment: "".into(),
|
||||||
typ: TokenType::END,
|
typ: TokenType::END,
|
||||||
pos: Position::from(&i),
|
pos: Position::from(&i),
|
||||||
});
|
});
|
||||||
@ -688,10 +689,12 @@ macro_rules! match_token {
|
|||||||
($i:expr, $t:expr, $f:expr, $msg:expr, $h:expr) => {{
|
($i:expr, $t:expr, $f:expr, $msg:expr, $h:expr) => {{
|
||||||
use abortable_parser::Result;
|
use abortable_parser::Result;
|
||||||
use std;
|
use std;
|
||||||
|
use std::rc::Rc;
|
||||||
|
let f: Rc<str> = $f.into();
|
||||||
let mut i_ = $i.clone();
|
let mut i_ = $i.clone();
|
||||||
let tok = i_.next();
|
let tok = i_.next();
|
||||||
if let Some(tok) = tok {
|
if let Some(tok) = tok {
|
||||||
if tok.typ == $t && &tok.fragment == $f {
|
if tok.typ == $t && tok.fragment.as_ref() == f.as_ref() {
|
||||||
match $h(tok) {
|
match $h(tok) {
|
||||||
std::result::Result::Ok(v) => Result::Complete(i_.clone(), v),
|
std::result::Result::Ok(v) => Result::Complete(i_.clone(), v),
|
||||||
std::result::Result::Err(e) => {
|
std::result::Result::Err(e) => {
|
||||||
|
@ -11,7 +11,7 @@ fn test_empty_token() {
|
|||||||
let result = emptytok(OffsetStrIter::new("NULL "));
|
let result = emptytok(OffsetStrIter::new("NULL "));
|
||||||
assert!(result.is_complete(), "result {:?} is not done", result);
|
assert!(result.is_complete(), "result {:?} is not done", result);
|
||||||
if let Result::Complete(_, tok) = result {
|
if let Result::Complete(_, tok) = result {
|
||||||
assert_eq!(tok.fragment, "NULL");
|
assert_eq!(tok.fragment.as_ref(), "NULL");
|
||||||
assert_eq!(tok.typ, TokenType::EMPTY);
|
assert_eq!(tok.typ, TokenType::EMPTY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -21,7 +21,7 @@ fn test_assert_token() {
|
|||||||
let result = asserttok(OffsetStrIter::new("assert "));
|
let result = asserttok(OffsetStrIter::new("assert "));
|
||||||
assert!(result.is_complete(), "result {:?} is not done", result);
|
assert!(result.is_complete(), "result {:?} is not done", result);
|
||||||
if let Result::Complete(_, tok) = result {
|
if let Result::Complete(_, tok) = result {
|
||||||
assert_eq!(tok.fragment, "assert");
|
assert_eq!(tok.fragment.as_ref(), "assert");
|
||||||
assert_eq!(tok.typ, TokenType::BAREWORD);
|
assert_eq!(tok.typ, TokenType::BAREWORD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ fn test_out_token() {
|
|||||||
let result = outtok(OffsetStrIter::new("out "));
|
let result = outtok(OffsetStrIter::new("out "));
|
||||||
assert!(result.is_complete(), "result {:?} is not done", result);
|
assert!(result.is_complete(), "result {:?} is not done", result);
|
||||||
if let Result::Complete(_, tok) = result {
|
if let Result::Complete(_, tok) = result {
|
||||||
assert_eq!(tok.fragment, "out");
|
assert_eq!(tok.fragment.as_ref(), "out");
|
||||||
assert_eq!(tok.typ, TokenType::BAREWORD);
|
assert_eq!(tok.typ, TokenType::BAREWORD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ fn test_out_token_with_comment() {
|
|||||||
let result = outtok(OffsetStrIter::new("out//comment"));
|
let result = outtok(OffsetStrIter::new("out//comment"));
|
||||||
assert!(result.is_complete(), "result {:?} is not done", result);
|
assert!(result.is_complete(), "result {:?} is not done", result);
|
||||||
if let Result::Complete(_, tok) = result {
|
if let Result::Complete(_, tok) = result {
|
||||||
assert_eq!(tok.fragment, "out");
|
assert_eq!(tok.fragment.as_ref(), "out");
|
||||||
assert_eq!(tok.typ, TokenType::BAREWORD);
|
assert_eq!(tok.typ, TokenType::BAREWORD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ fn test_string_with_escaping() {
|
|||||||
let result = strtok(OffsetStrIter::new("\"foo \\\\ \\\"bar\""));
|
let result = strtok(OffsetStrIter::new("\"foo \\\\ \\\"bar\""));
|
||||||
assert!(result.is_complete(), "result {:?} is not ok", result);
|
assert!(result.is_complete(), "result {:?} is not ok", result);
|
||||||
if let Result::Complete(_, tok) = result {
|
if let Result::Complete(_, tok) = result {
|
||||||
assert_eq!(tok.fragment, "foo \\ \"bar".to_string());
|
assert_eq!(tok.fragment.as_ref(), "foo \\ \"bar".to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ fn test_tokenize_bareword_with_dash() {
|
|||||||
assert!(result.is_ok(), "result {:?} is not ok", result);
|
assert!(result.is_ok(), "result {:?} is not ok", result);
|
||||||
if let Ok(toks) = result {
|
if let Ok(toks) = result {
|
||||||
assert_eq!(toks.len(), 2);
|
assert_eq!(toks.len(), 2);
|
||||||
assert_eq!(toks[0].fragment, "foo-bar");
|
assert_eq!(toks[0].fragment.as_ref(), "foo-bar");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ macro_rules! assert_token {
|
|||||||
);
|
);
|
||||||
if let Result::Complete(_, tok) = result {
|
if let Result::Complete(_, tok) = result {
|
||||||
assert_eq!(tok.typ, $typ);
|
assert_eq!(tok.typ, $typ);
|
||||||
assert_eq!(tok.fragment, $input);
|
assert_eq!(tok.fragment.as_ref(), $input);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ fn test_parse_comment() {
|
|||||||
cmt,
|
cmt,
|
||||||
Token {
|
Token {
|
||||||
typ: TokenType::COMMENT,
|
typ: TokenType::COMMENT,
|
||||||
fragment: " comment".to_string(),
|
fragment: " comment".into(),
|
||||||
pos: Position {
|
pos: Position {
|
||||||
file: None,
|
file: None,
|
||||||
line: 1,
|
line: 1,
|
||||||
@ -221,7 +221,7 @@ fn test_parse_comment() {
|
|||||||
cmt,
|
cmt,
|
||||||
Token {
|
Token {
|
||||||
typ: TokenType::COMMENT,
|
typ: TokenType::COMMENT,
|
||||||
fragment: " comment".to_string(),
|
fragment: " comment".into(),
|
||||||
pos: Position {
|
pos: Position {
|
||||||
file: None,
|
file: None,
|
||||||
column: 1,
|
column: 1,
|
||||||
@ -238,7 +238,7 @@ fn test_parse_comment() {
|
|||||||
cmt,
|
cmt,
|
||||||
Token {
|
Token {
|
||||||
typ: TokenType::COMMENT,
|
typ: TokenType::COMMENT,
|
||||||
fragment: " comment".to_string(),
|
fragment: " comment".into(),
|
||||||
pos: Position {
|
pos: Position {
|
||||||
file: None,
|
file: None,
|
||||||
column: 1,
|
column: 1,
|
||||||
@ -254,7 +254,7 @@ fn test_parse_comment() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_match_word() {
|
fn test_match_word() {
|
||||||
let input = vec![Token {
|
let input = vec![Token {
|
||||||
fragment: "foo".to_string(),
|
fragment: "foo".into(),
|
||||||
typ: TokenType::BAREWORD,
|
typ: TokenType::BAREWORD,
|
||||||
pos: Position {
|
pos: Position {
|
||||||
file: None,
|
file: None,
|
||||||
@ -273,7 +273,7 @@ fn test_match_word() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_match_word_empty_input() {
|
fn test_match_word_empty_input() {
|
||||||
let input = vec![Token {
|
let input = vec![Token {
|
||||||
fragment: "".to_string(),
|
fragment: "".into(),
|
||||||
typ: TokenType::END,
|
typ: TokenType::END,
|
||||||
pos: Position {
|
pos: Position {
|
||||||
file: None,
|
file: None,
|
||||||
@ -296,7 +296,7 @@ fn test_match_word_empty_input() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_match_punct() {
|
fn test_match_punct() {
|
||||||
let input = vec![Token {
|
let input = vec![Token {
|
||||||
fragment: "!".to_string(),
|
fragment: "!".into(),
|
||||||
typ: TokenType::PUNCT,
|
typ: TokenType::PUNCT,
|
||||||
pos: Position {
|
pos: Position {
|
||||||
file: None,
|
file: None,
|
||||||
@ -315,7 +315,7 @@ fn test_match_punct() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_match_type() {
|
fn test_match_type() {
|
||||||
let input = vec![Token {
|
let input = vec![Token {
|
||||||
fragment: "foo".to_string(),
|
fragment: "foo".into(),
|
||||||
typ: TokenType::BAREWORD,
|
typ: TokenType::BAREWORD,
|
||||||
pos: Position {
|
pos: Position {
|
||||||
file: None,
|
file: None,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user