add serialization of values

This commit is contained in:
Matthieu Jolimaitre 2024-10-24 06:03:40 +02:00
parent da82c775db
commit 6350e4a40f
5 changed files with 87 additions and 26 deletions

View file

@ -86,8 +86,8 @@ pub struct FunDef {
impl FunDef {
pub fn parser_def(instr: impl Parse<Instr>, expr: impl Parse<Expr>) -> impl Parse<(String, Self)> {
let arguments = id().separated_by(lx(","));
(lx("fn").ignore_then(id()))
let arguments = id().padded().separated_by(lx(","));
(lx("fn").ignore_then(id().padded()))
.then(lx("(").ignore_then(arguments).then_ignore(lx(")")))
.then(lx("{").ignore_then(Block::parser(instr, expr)).then_ignore(lx("}")))
.map(|((id, args), body)| (id, Self { args, body }))
@ -95,7 +95,7 @@ impl FunDef {
}
pub fn parser_lamb(instr: impl Parse<Instr>, expr: impl Parse<Expr>) -> impl Parse<Self> {
let arguments = id().separated_by(lx(","));
let arguments = id().padded().separated_by(lx(","));
(lx("(").ignore_then(arguments).then_ignore(lx(")")))
.then(lx("{").ignore_then(Block::parser(instr, expr)).then_ignore(lx("}")))
.map(|(args, body)| Self { args, body })
@ -258,7 +258,7 @@ impl Expr {
.map(|(f, o)| Self::BinOps(f.to_box(), o))
.or((left.clone())
.then_ignore(lx("."))
.then(id())
.then(id().padded())
.map(|(e, a)| Self::Access(e.to_box(), a)))
.or((left.clone())
.then_ignore(lx("("))

View file

@ -4,7 +4,11 @@ mod util;
use core::{cell::RefCell, fmt::Debug, iter::repeat};
use alloc::{rc::Rc, string::String, vec::Vec};
use alloc::{
rc::Rc,
string::{String, ToString},
vec::Vec,
};
use ast::{Block, FunDef, Short};
use chumsky::{error::Simple, Parser};
@ -121,6 +125,54 @@ pub enum Value {
Function(Rc<RefCell<Function>>),
}
impl Value {
pub fn serialize(&self) -> String {
match self {
Self::None => "none".to_string(),
Self::Bool(b) => b.to_string(),
Self::Num(n) => n.to_string(),
Self::Str(s) => s.to_string(),
Self::Object(o) => {
let mut res = "{".to_string();
let mut first = true;
for (name, value) in o.borrow().iter() {
if first {
res += " ";
res += name;
res += ": ";
res += &value.serialize();
first = false;
} else {
res += ", ";
res += name;
res += ": ";
res += &value.serialize();
}
}
res += " }";
res
}
Self::Array(a) => {
let mut res = "[".to_string();
let mut first = true;
for value in a.borrow().iter() {
if first {
res += " ";
res += &value.serialize();
first = false;
} else {
res += ", ";
res += &value.serialize();
}
}
res += " ]";
res
}
Self::Function(_f) => "<function>".to_string(),
}
}
}
pub enum InstrOutput {
Short(Short),
Value(Value),
@ -135,9 +187,12 @@ pub struct Function {
#[derive(Clone)]
pub enum FunImpl {
Def(FunDef),
Built(Rc<dyn Fn(Vec<Value>, &mut Context) -> Result<Value, EvalError>>),
Built(Rc<BuiltFun>),
}
pub type FunRes = Result<Value, EvalError>;
pub type BuiltFun = dyn Fn(Vec<Value>, &mut Context) -> FunRes;
impl Debug for FunImpl {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
@ -168,21 +223,3 @@ impl Function {
}
pub mod ast;
/*
let a = 3;
fn f1() {
let a = 5;
fn f2() {
a = 3;
}
f2
}
let f2 = f1();
f2();
a = 3
*/