Skip to content

Commit

Permalink
Add full support for comments in MOROS Lisp (#489)
Browse files Browse the repository at this point in the history
* Add full support for Lisp comments

* Update changelog

* Update doc
  • Loading branch information
vinc authored May 24, 2023
1 parent 4e46f39 commit 9c850e1
Show file tree
Hide file tree
Showing 16 changed files with 58 additions and 64 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
1 change: 1 addition & 0 deletions doc/lisp.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
11 changes: 4 additions & 7 deletions src/usr/lisp/eval.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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))
}
Expand Down
71 changes: 26 additions & 45 deletions src/usr/lisp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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
Expand All @@ -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)
}
}
Expand All @@ -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)
};
}

Expand Down
15 changes: 14 additions & 1 deletion src/usr/lisp/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -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"))),
}
}
2 changes: 1 addition & 1 deletion www/calculator.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
2 changes: 1 addition & 1 deletion www/editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
2 changes: 1 addition & 1 deletion www/filesystem.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
2 changes: 1 addition & 1 deletion www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
3 changes: 2 additions & 1 deletion www/lisp.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -220,6 +220,7 @@ <h3>0.5.0 (unpublished)</h3>

<ul>
<li>Rename or add aliases to many functions</li>
<li>Add full support for line and inline comments</li>
</ul>
</body>
</html>
2 changes: 1 addition & 1 deletion www/manual.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
2 changes: 1 addition & 1 deletion www/network.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
2 changes: 1 addition & 1 deletion www/regex.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
2 changes: 1 addition & 1 deletion www/shell.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
2 changes: 1 addition & 1 deletion www/syscalls.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
2 changes: 1 addition & 1 deletion www/test.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down

0 comments on commit 9c850e1

Please sign in to comment.