mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
DEV: Simple formatting works
This commit is contained in:
parent
422569c7b4
commit
405ad2880e
@ -20,8 +20,8 @@ impl<E> From<E> for Error
|
||||
where
|
||||
E: std::error::Error + Sized,
|
||||
{
|
||||
fn from(_e: E) -> Error {
|
||||
fn from(_e: E) -> Self {
|
||||
// FIXME(jwall): This should really have more information for debugging
|
||||
Error {}
|
||||
}
|
||||
}
|
||||
}
|
@ -40,6 +40,18 @@ pub enum Primitive {
|
||||
|
||||
use Primitive::{Bool, Empty, Float, Int, Str};
|
||||
|
||||
impl From<&Primitive> for String {
|
||||
fn from(p: &Primitive) -> Self {
|
||||
match p {
|
||||
Int(i) => format!("{}", i),
|
||||
Float(f) => format!("{}", f),
|
||||
Str(s) => format!("{}", s),
|
||||
Bool(b) => format!("{}", b),
|
||||
Empty => "NULL".to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Composite {
|
||||
List(Vec<Rc<Value>>),
|
||||
@ -48,6 +60,35 @@ pub enum Composite {
|
||||
|
||||
use Composite::{List, Tuple};
|
||||
|
||||
impl From<&Composite> for String {
|
||||
fn from(c: &Composite) -> Self {
|
||||
let mut buf = String::new();
|
||||
match c {
|
||||
&List(ref elems) => {
|
||||
buf.push_str("[");
|
||||
for e in elems.iter() {
|
||||
let val: String = e.as_ref().into();
|
||||
buf.push_str(&val);
|
||||
buf.push_str(",");
|
||||
}
|
||||
buf.push_str("]");
|
||||
}
|
||||
&Tuple(ref flds) => {
|
||||
buf.push_str("{");
|
||||
for &(ref k, ref v) in flds.iter() {
|
||||
buf.push_str(&k);
|
||||
buf.push_str(" = ");
|
||||
let val: String = v.as_ref().into();
|
||||
buf.push_str(&val);
|
||||
buf.push_str(",");
|
||||
}
|
||||
buf.push_str("}");
|
||||
}
|
||||
}
|
||||
buf
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Func {
|
||||
ptr: OpPointer,
|
||||
@ -78,6 +119,19 @@ pub enum Value {
|
||||
M(Module),
|
||||
}
|
||||
|
||||
impl From<&Value> for String {
|
||||
fn from(v: &Value) -> Self {
|
||||
match v {
|
||||
&S(ref s) => s.clone(),
|
||||
&P(ref p) => p.into(),
|
||||
&C(ref c) => c.into(),
|
||||
&T(_) => "<Thunk>".to_owned(),
|
||||
&F(_) => "<Func>".to_owned(),
|
||||
&M(_) => "<Module>".to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use Value::{C, F, M, P, S, T};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
@ -148,6 +202,8 @@ pub enum Op {
|
||||
// Runtime hooks
|
||||
Runtime(Hook),
|
||||
// TODO(jwall): TRACE instruction
|
||||
// TODO(jwall): Format instruction
|
||||
Format,
|
||||
}
|
||||
|
||||
use super::ir::Val;
|
||||
|
@ -16,7 +16,7 @@ use std::rc::Rc;
|
||||
use super::scope::Stack;
|
||||
use super::Composite::{List, Tuple};
|
||||
use super::Op::{
|
||||
Add, Bang, Bind, Cp, DeRef, Div, Element, Equal, FCall, Field, Func, Index, InitList,
|
||||
Add, Bang, Bind, Cp, DeRef, Div, Element, Equal, FCall, Field, Format, Func, Index, InitList,
|
||||
InitThunk, InitTuple, Jump, JumpIfFalse, JumpIfTrue, Module, Mul, Noop, Pop, Return,
|
||||
SelectJump, Sub, Sym, Typ, Val,
|
||||
};
|
||||
@ -632,3 +632,18 @@ fn simple_not_expr() {
|
||||
"not 1!=1;" => P(Bool(true)),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn simple_format_expr() {
|
||||
assert_cases![
|
||||
vec![
|
||||
InitList,
|
||||
Val(Int(1)),
|
||||
Element,
|
||||
Val(Int(2)),
|
||||
Element,
|
||||
Val(Str("@@".to_owned())),
|
||||
Format,
|
||||
] => P(Str("12".to_owned())),
|
||||
];
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
use crate::ast::{BinaryExprType, Expression, Statement, Value};
|
||||
use crate::ast::{BinaryExprType, Expression, Statement, Value, FormatArgs};
|
||||
use crate::build::opcode::Primitive;
|
||||
use crate::build::opcode::Value::{C, F, M, P, T};
|
||||
use crate::build::opcode::{Hook, Op};
|
||||
@ -168,7 +168,24 @@ impl AST {
|
||||
Self::translate_expr(*expr, &mut ops);
|
||||
}
|
||||
Expression::Fail(_) => unimplemented!("Fail expressions are not implmented yet"),
|
||||
Expression::Format(_) => unimplemented!("Format expressions are not implmented yet"),
|
||||
Expression::Format(def) => {
|
||||
match def.args {
|
||||
FormatArgs::List(elems) => {
|
||||
ops.push(Op::InitList);
|
||||
for e in elems {
|
||||
Self::translate_expr(e, &mut ops);
|
||||
ops.push(Op::Element);
|
||||
}
|
||||
}
|
||||
FormatArgs::Single(e) => {
|
||||
ops.push(Op::InitList);
|
||||
Self::translate_expr(*e, &mut ops);
|
||||
ops.push(Op::Element);
|
||||
}
|
||||
}
|
||||
ops.push(Op::Val(Primitive::Str(def.template)));
|
||||
ops.push(Op::Format);
|
||||
}
|
||||
Expression::Func(_) => unimplemented!("Func expressions are not implmented yet"),
|
||||
Expression::FuncOp(_) => unimplemented!("FuncOp expressions are not implmented yet"),
|
||||
Expression::Import(_) => unimplemented!("Import expressions are not implmented yet"),
|
||||
|
@ -18,13 +18,14 @@ use std::rc::Rc;
|
||||
use super::pointer::OpPointer;
|
||||
use super::runtime;
|
||||
use super::scope::Stack;
|
||||
use super::{Error, Op, Primitive, Value};
|
||||
|
||||
use super::Composite::{List, Tuple};
|
||||
use super::Hook;
|
||||
use super::Primitive::{Bool, Empty, Float, Int, Str};
|
||||
use super::Value::{C, F, M, P, S, T};
|
||||
use super::{Error, Op, Primitive, Value};
|
||||
use super::{Func, Module};
|
||||
use crate::ast::Position;
|
||||
use crate::build::format::{ExpressionFormatter, FormatRenderer, SimpleFormatter};
|
||||
|
||||
pub struct VM {
|
||||
stack: Vec<Rc<Value>>,
|
||||
@ -123,6 +124,7 @@ impl<'a> VM {
|
||||
}
|
||||
Op::Typ => self.op_typ()?,
|
||||
Op::Runtime(h) => self.op_runtime(h)?,
|
||||
Op::Format => self.op_format()?,
|
||||
};
|
||||
}
|
||||
Ok(())
|
||||
@ -719,4 +721,28 @@ impl<'a> VM {
|
||||
.borrow_mut()
|
||||
.handle(&self.path, h, &mut self.stack)
|
||||
}
|
||||
|
||||
fn op_format(&mut self) -> Result<(), Error> {
|
||||
let template = self.pop()?;
|
||||
let template = match template.as_ref() {
|
||||
&P(Str(ref s)) => s.clone(),
|
||||
_ => return Err(dbg!(Error {})),
|
||||
};
|
||||
let args = self.pop()?;
|
||||
let args: Vec<&Value> = match args.as_ref() {
|
||||
&C(List(ref elems)) => elems.iter().map(|v| v.as_ref()).collect(),
|
||||
_ => return Err(dbg!(Error {})),
|
||||
};
|
||||
let f = if args.len() == 1 {
|
||||
unimplemented!("Expression formatters are not implemented yet");
|
||||
} else {
|
||||
SimpleFormatter::new(template, args)
|
||||
};
|
||||
// TODO(jwall): Position should be valid here.
|
||||
match dbg!(f.render(&Position::new(0, 0, 0))) {
|
||||
Err(_e) => return Err(dbg!(Error {})),
|
||||
Ok(s) => self.push(Rc::new(P(Str(s))))?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user