mirror of https://github.com/vinc/moros.git
Add full support for comments in MOROS Lisp (#489)
* Add full support for Lisp comments * Update changelog * Update doc
This commit is contained in:
parent
4e46f39433
commit
9c850e108b
|
@ -1,6 +1,7 @@
|
|||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
- Add full support for comments in lisp (#489)
|
||||
- Add parenthesis matching to editor (#488)
|
||||
- Upgrade smoltcp from 0.8.2 to 0.9.1 (#484)
|
||||
- Update rust to nightly-2022-12-21 (#485)
|
||||
|
|
|
@ -187,3 +187,4 @@ Rewrite parts of the code and add new functions and examples.
|
|||
|
||||
### 0.5.0 (unpublished)
|
||||
- Rename or add aliases to many functions
|
||||
- Add full support for line and inline comments
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use super::{Err, Exp, Env, Function};
|
||||
use super::{Err, Exp, Env, Function, parse_eval};
|
||||
use super::env::{env_get, env_set, function_env};
|
||||
use super::parse::parse;
|
||||
use super::expand::expand;
|
||||
use super::string;
|
||||
|
||||
|
@ -130,15 +129,13 @@ fn eval_do_args(args: &[Exp], env: &mut Rc<RefCell<Env>>) -> Result<Exp, Err> {
|
|||
fn eval_load_args(args: &[Exp], env: &mut Rc<RefCell<Env>>) -> Result<Exp, Err> {
|
||||
ensure_length_eq!(args, 1);
|
||||
let path = string(&args[0])?;
|
||||
let mut code = fs::read_to_string(&path).or(Err(Err::Reason("Could not read file".to_string())))?;
|
||||
let mut input = fs::read_to_string(&path).or(Err(Err::Reason(format!("File not found '{}'", path))))?;
|
||||
loop {
|
||||
let (rest, exp) = parse(&code)?;
|
||||
let exp = expand(&exp, env)?;
|
||||
eval(&exp, env)?;
|
||||
let (rest, _) = parse_eval(&input, env)?;
|
||||
if rest.is_empty() {
|
||||
break;
|
||||
}
|
||||
code = rest;
|
||||
input = rest;
|
||||
}
|
||||
Ok(Exp::Bool(true))
|
||||
}
|
||||
|
|
|
@ -182,16 +182,11 @@ pub fn byte(exp: &Exp) -> Result<u8, Err> {
|
|||
|
||||
// REPL
|
||||
|
||||
fn parse_eval(exp: &str, env: &mut Rc<RefCell<Env>>) -> Result<Exp, Err> {
|
||||
let (_, exp) = parse(exp)?;
|
||||
fn parse_eval(input: &str, env: &mut Rc<RefCell<Env>>) -> Result<(String, Exp), Err> {
|
||||
let (rest, exp) = parse(input)?;
|
||||
let exp = expand(&exp, env)?;
|
||||
let exp = eval(&exp, env)?;
|
||||
Ok(exp)
|
||||
}
|
||||
|
||||
fn strip_comments(s: &str) -> String {
|
||||
// FIXME: This doesn't handle `#` inside a string
|
||||
s.split('#').next().unwrap().into()
|
||||
Ok((rest, exp))
|
||||
}
|
||||
|
||||
fn lisp_completer(line: &str) -> Vec<String> {
|
||||
|
@ -221,33 +216,29 @@ fn repl(env: &mut Rc<RefCell<Env>>) -> Result<(), ExitCode> {
|
|||
prompt.history.load(history_file);
|
||||
prompt.completion.set(&lisp_completer);
|
||||
|
||||
while let Some(line) = prompt.input(&prompt_string) {
|
||||
if line == "(quit)" {
|
||||
while let Some(input) = prompt.input(&prompt_string) {
|
||||
if input == "(quit)" {
|
||||
break;
|
||||
}
|
||||
if line.is_empty() {
|
||||
if input.is_empty() {
|
||||
println!();
|
||||
continue;
|
||||
}
|
||||
match parse_eval(&line, env) {
|
||||
Ok(res) => {
|
||||
println!("{}\n", res);
|
||||
match parse_eval(&input, env) {
|
||||
Ok((_, exp)) => {
|
||||
println!("{}\n", exp);
|
||||
}
|
||||
Err(e) => match e {
|
||||
Err::Reason(msg) => println!("{}Error:{} {}\n", csi_error, csi_reset, msg),
|
||||
},
|
||||
}
|
||||
prompt.history.add(&line);
|
||||
prompt.history.add(&input);
|
||||
prompt.history.save(history_file);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn main(args: &[&str]) -> Result<(), ExitCode> {
|
||||
let line_color = Style::color("Yellow");
|
||||
let error_color = Style::color("LightRed");
|
||||
let reset = Style::reset();
|
||||
|
||||
let env = &mut default_env();
|
||||
|
||||
// Store args in env
|
||||
|
@ -269,37 +260,27 @@ pub fn main(args: &[&str]) -> Result<(), ExitCode> {
|
|||
if args[1] == "-h" || args[1] == "--help" {
|
||||
return help();
|
||||
}
|
||||
let pathname = args[1];
|
||||
if let Ok(code) = api::fs::read_to_string(pathname) {
|
||||
let mut block = String::new();
|
||||
let mut opened = 0;
|
||||
let mut closed = 0;
|
||||
for (i, line) in code.split('\n').enumerate() {
|
||||
let line = strip_comments(line);
|
||||
if !line.is_empty() {
|
||||
opened += line.matches('(').count();
|
||||
closed += line.matches(')').count();
|
||||
block.push_str(&line);
|
||||
if closed >= opened {
|
||||
if let Err(e) = parse_eval(&block, env) {
|
||||
match e {
|
||||
Err::Reason(msg) => {
|
||||
eprintln!("{}Error:{} {}", error_color, reset, msg);
|
||||
eprintln!();
|
||||
eprintln!(" {}{}:{} {}", line_color, i, reset, line);
|
||||
return Err(ExitCode::Failure);
|
||||
}
|
||||
}
|
||||
let path = args[1];
|
||||
if let Ok(mut input) = api::fs::read_to_string(path) {
|
||||
loop {
|
||||
match parse_eval(&input, env) {
|
||||
Ok((rest, _)) => {
|
||||
if rest.is_empty() {
|
||||
break;
|
||||
}
|
||||
block.clear();
|
||||
opened = 0;
|
||||
closed = 0;
|
||||
input = rest;
|
||||
}
|
||||
Err(Err::Reason(msg)) => {
|
||||
let csi_error = Style::color("LightRed");
|
||||
let csi_reset = Style::reset();
|
||||
eprintln!("{}Error:{} {}", csi_error, csi_reset, msg);
|
||||
return Err(ExitCode::Failure);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
error!("File not found '{}'", pathname);
|
||||
error!("File not found '{}'", path);
|
||||
Err(ExitCode::Failure)
|
||||
}
|
||||
}
|
||||
|
@ -320,7 +301,7 @@ fn test_lisp() {
|
|||
|
||||
macro_rules! eval {
|
||||
($e:expr) => {
|
||||
format!("{}", parse_eval($e, env).unwrap())
|
||||
format!("{}", parse_eval($e, env).unwrap().1)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ use alloc::string::String;
|
|||
use alloc::string::ToString;
|
||||
use alloc::vec;
|
||||
|
||||
use nom::Err::Error;
|
||||
use nom::IResult;
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::escaped_transform;
|
||||
|
@ -91,7 +92,15 @@ fn parse_quasiquote(input: &str) -> IResult<&str, Exp> {
|
|||
Ok((input, Exp::List(list)))
|
||||
}
|
||||
|
||||
use nom::sequence::pair;
|
||||
use alloc::format;
|
||||
|
||||
fn parse_comment(input: &str) -> IResult<&str, ()> {
|
||||
value((), pair(char('#'), is_not("\n")))(input)
|
||||
}
|
||||
|
||||
fn parse_exp(input: &str) -> IResult<&str, Exp> {
|
||||
let (input, _) = opt(parse_comment)(input)?;
|
||||
delimited(multispace0, alt((
|
||||
parse_num, parse_bool, parse_str, parse_list, parse_quote, parse_quasiquote, parse_unquote_splice, parse_unquote, parse_splice, parse_sym
|
||||
)), multispace0)(input)
|
||||
|
@ -100,6 +109,10 @@ fn parse_exp(input: &str) -> IResult<&str, Exp> {
|
|||
pub fn parse(input: &str)-> Result<(String, Exp), Err> {
|
||||
match parse_exp(input) {
|
||||
Ok((input, exp)) => Ok((input.to_string(), exp)),
|
||||
Err(_) => Err(Err::Reason("Could not parse input".to_string())),
|
||||
Err(Error(err)) if !err.input.is_empty() => {
|
||||
let line = err.input.lines().next().unwrap();
|
||||
Err(Err::Reason(format!("Could not parse '{}'", line)))
|
||||
}
|
||||
_ => Err(Err::Reason(format!("Could not parse input"))),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>MOROS Calculator</title>
|
||||
<link rel="stylesheet" type="text/css" href="/moros.css">
|
||||
<link rel="stylesheet" type="text/css" href="moros.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>MOROS Calculator</h1>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>MOROS Editor</title>
|
||||
<link rel="stylesheet" type="text/css" href="/moros.css">
|
||||
<link rel="stylesheet" type="text/css" href="moros.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>MOROS Editor</h1>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>MOROS Filesystem</title>
|
||||
<link rel="stylesheet" type="text/css" href="/moros.css">
|
||||
<link rel="stylesheet" type="text/css" href="moros.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>MOROS Filesystem</h1>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>MOROS: Obscure Rust Operating System</title>
|
||||
<link rel="stylesheet" type="text/css" href="/moros.css">
|
||||
<link rel="stylesheet" type="text/css" href="moros.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>MOROS: Obscure Rust Operating System</h1>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>MOROS Lisp</title>
|
||||
<link rel="stylesheet" type="text/css" href="/moros.css">
|
||||
<link rel="stylesheet" type="text/css" href="moros.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>MOROS Lisp</h1>
|
||||
|
@ -220,6 +220,7 @@ language and reading from the filesystem.</p>
|
|||
|
||||
<ul>
|
||||
<li>Rename or add aliases to many functions</li>
|
||||
<li>Add full support for line and inline comments</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>MOROS Manual</title>
|
||||
<link rel="stylesheet" type="text/css" href="/moros.css">
|
||||
<link rel="stylesheet" type="text/css" href="moros.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>MOROS Manual</h1>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>MOROS Network</title>
|
||||
<link rel="stylesheet" type="text/css" href="/moros.css">
|
||||
<link rel="stylesheet" type="text/css" href="moros.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>MOROS Network</h1>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>MOROS Regular Expression Engine</title>
|
||||
<link rel="stylesheet" type="text/css" href="/moros.css">
|
||||
<link rel="stylesheet" type="text/css" href="moros.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>MOROS Regular Expression Engine</h1>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>MOROS Shell</title>
|
||||
<link rel="stylesheet" type="text/css" href="/moros.css">
|
||||
<link rel="stylesheet" type="text/css" href="moros.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>MOROS Shell</h1>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>MOROS Syscalls</title>
|
||||
<link rel="stylesheet" type="text/css" href="/moros.css">
|
||||
<link rel="stylesheet" type="text/css" href="moros.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>MOROS Syscalls</h1>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>MOROS</title>
|
||||
<link rel="stylesheet" type="text/css" href="/moros.css">
|
||||
<link rel="stylesheet" type="text/css" href="moros.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>MOROS</h1>
|
||||
|
|
Loading…
Reference in New Issue