Skip to content

Commit 1ae4caa

Browse files
committed
Refactor code and update dependencies
1 parent b4ddce8 commit 1ae4caa

File tree

5 files changed

+197
-190
lines changed

5 files changed

+197
-190
lines changed

Cargo.toml

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ keywords = ["pancake", "stack", "esoteric", "parser", "interpreter"]
1616
maintenance = { status = "passively-maintained" }
1717

1818
[dependencies]
19-
"regex" = "1.4"
20-
"lazy_static" = "1.4"
21-
"unicode-segmentation" = "1.7"
19+
"regex" = "1.8"
20+
"lazy-regex" = "2.5"
21+
"unicode-segmentation" = "1.10"
2222

2323
[dev-dependencies]
24-
criterion = "0.3"
24+
criterion = "0.4"
2525

2626
[[bench]]
2727
name = "bench"

src/interpret.rs

+42-50
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::parse::{parse_program_str, BorrowedCommand, OwnedCommand};
1+
use crate::parse::{parse_program_str, Command};
22
use std::collections::HashMap;
33
use std::fmt::{self, Display};
44
use std::io::{self, prelude::*, BufReader, Read, Write};
@@ -63,7 +63,7 @@ where
6363
}
6464
}
6565

66-
let c = OwnedCommand::from_line(&program_line);
66+
let c = Command::from_line(&program_line);
6767
if c.is_err() {
6868
if !program_line.trim().is_empty() {
6969
eprintln!("invalid command: \"{}\"", program_line);
@@ -75,20 +75,18 @@ where
7575
executed.last().unwrap()
7676
};
7777

78-
// println!("{:?} {:?}", stack, command);
79-
8078
// TODO: Deduplicate this code
8179
match command {
82-
OwnedCommand::PutThisPancakeOnTop(adjective) => {
80+
Command::PutThisPancakeOnTop(adjective) => {
8381
stack.push(adjective.graphemes(true).count() as u32);
8482
}
85-
OwnedCommand::EatThePancakeOnTop => {
83+
Command::EatThePancakeOnTop => {
8684
if stack.is_empty() {
8785
return Err(Error::OutOfPancakes);
8886
}
8987
stack.pop();
9088
}
91-
OwnedCommand::PutTheTopPancakesTogether => {
89+
Command::PutTheTopPancakesTogether => {
9290
if stack.len() < 2 {
9391
return Err(Error::OutOfPancakes);
9492
}
@@ -97,29 +95,29 @@ where
9795
let result = first.checked_add(second).ok_or(Error::PancakeOverflow)?;
9896
stack.push(result);
9997
}
100-
OwnedCommand::GiveMeAPancake => {
98+
Command::GiveMeAPancake => {
10199
input.read_line(&mut in_line)?;
102100
let number_input = in_line
103101
.parse()
104102
.map_err(|_| Error::InvalidPancake(in_line.clone()))?;
105103
stack.push(number_input);
106104
in_line.clear();
107105
}
108-
OwnedCommand::HowAboutAHotcake => {
106+
Command::HowAboutAHotcake => {
109107
let buf = input.fill_buf()?;
110-
let number_input = *buf.get(0).unwrap_or(&0);
108+
let number_input = *buf.first().unwrap_or(&0);
111109
input.consume(1);
112110
stack.push(u32::from(number_input));
113111
}
114-
OwnedCommand::ShowMeAPancake => {
112+
Command::ShowMeAPancake => {
115113
if stack.is_empty() {
116114
return Err(Error::OutOfPancakes);
117115
}
118116
let top = stack.last().unwrap();
119117
let c = char::from_u32(*top).ok_or(Error::CanNotShowPancake(*top))?;
120118
write!(output, "{}", c)?;
121119
}
122-
OwnedCommand::TakeFromTheTopPancakes => {
120+
Command::TakeFromTheTopPancakes => {
123121
if stack.len() < 2 {
124122
return Err(Error::OutOfPancakes);
125123
}
@@ -128,7 +126,7 @@ where
128126
let result = first.checked_sub(second).ok_or(Error::PancakeUnderflow)?;
129127
stack.push(result);
130128
}
131-
OwnedCommand::FlipThePancakesOnTop => {
129+
Command::FlipThePancakesOnTop => {
132130
if stack.len() < 2 {
133131
return Err(Error::OutOfPancakes);
134132
}
@@ -137,68 +135,68 @@ where
137135
stack.push(first);
138136
stack.push(second);
139137
}
140-
OwnedCommand::PutAnotherPancakeOnTop => {
138+
Command::PutAnotherPancakeOnTop => {
141139
if stack.is_empty() {
142140
return Err(Error::OutOfPancakes);
143141
}
144142
stack.push(*stack.last().unwrap());
145143
}
146-
OwnedCommand::Label(label) => {
144+
Command::Label(label) => {
147145
if stack.is_empty() {
148146
return Err(Error::OutOfPancakes);
149147
}
150148
let top = stack.last().unwrap();
151149
labels.insert(label.clone(), (*top - 1) as usize);
152150
}
153-
OwnedCommand::IfThePancakeIsntTastyGoOverTo(target_label) => {
151+
Command::IfThePancakeIsntTastyGoOverTo(target_label) => {
154152
if stack.is_empty() {
155153
return Err(Error::OutOfPancakes);
156154
}
157155
let top = *stack.last().unwrap();
158156
if top == 0 {
159157
let label_position = labels
160158
.get(target_label)
161-
.ok_or_else(|| Error::UndefinedLabel(target_label.clone()))?;
159+
.ok_or_else(|| Error::UndefinedLabel(target_label.to_string()))?;
162160
current_statement = Some(*label_position);
163161
}
164162
}
165-
OwnedCommand::IfThePancakeIsTastyGoOverTo(target_label) => {
163+
Command::IfThePancakeIsTastyGoOverTo(target_label) => {
166164
if stack.is_empty() {
167165
return Err(Error::OutOfPancakes);
168166
}
169167
let top = *stack.last().unwrap();
170168
if top != 0 {
171169
let label_position = labels
172170
.get(target_label)
173-
.ok_or_else(|| Error::UndefinedLabel(target_label.clone()))?;
171+
.ok_or_else(|| Error::UndefinedLabel(target_label.to_string()))?;
174172
current_statement = Some(*label_position);
175173
}
176174
}
177-
OwnedCommand::PutSyrupOnThePancakes => {
175+
Command::PutSyrupOnThePancakes => {
178176
for value in &mut stack {
179177
*value = value.checked_add(1).ok_or(Error::PancakeOverflow)?;
180178
}
181179
}
182-
OwnedCommand::PutButterOnThePancakes => {
180+
Command::PutButterOnThePancakes => {
183181
if stack.is_empty() {
184182
return Err(Error::OutOfPancakes);
185183
}
186184
let top = stack.last_mut().unwrap();
187185
*top = top.checked_add(1).ok_or(Error::PancakeOverflow)?;
188186
}
189-
OwnedCommand::TakeOffTheSyrup => {
187+
Command::TakeOffTheSyrup => {
190188
for value in &mut stack {
191189
*value = value.checked_sub(1).ok_or(Error::PancakeUnderflow)?;
192190
}
193191
}
194-
OwnedCommand::TakeOffTheButter => {
192+
Command::TakeOffTheButter => {
195193
if stack.is_empty() {
196194
return Err(Error::OutOfPancakes);
197195
}
198196
let top = stack.last_mut().unwrap();
199197
*top = top.checked_sub(1).ok_or(Error::PancakeUnderflow)?;
200198
}
201-
OwnedCommand::EatAllOfThePancakes => {
199+
Command::EatAllOfThePancakes => {
202200
break;
203201
}
204202
}
@@ -256,11 +254,7 @@ where
256254
///
257255
/// # Errors
258256
/// Will return `Err` if the given program performs an illegal operation or an io error occurs. See [`Error`](./enum.Error.html).
259-
pub fn run_program<I, O>(
260-
program: &[BorrowedCommand<'_>],
261-
input: I,
262-
mut output: O,
263-
) -> Result<(), Error>
257+
pub fn run_program<I, O>(program: &[Command<'_>], input: I, mut output: O) -> Result<(), Error>
264258
where
265259
I: Read,
266260
O: Write,
@@ -275,20 +269,18 @@ where
275269
while let Some(command) = program.get(current_statement) {
276270
current_statement += 1;
277271

278-
// println!("{:?} {:?}", stack, command);
279-
280272
// TODO: Deduplicate this code
281273
match command {
282-
BorrowedCommand::PutThisPancakeOnTop(adjective) => {
274+
Command::PutThisPancakeOnTop(adjective) => {
283275
stack.push(adjective.graphemes(true).count() as u32);
284276
}
285-
BorrowedCommand::EatThePancakeOnTop => {
277+
Command::EatThePancakeOnTop => {
286278
if stack.is_empty() {
287279
return Err(Error::OutOfPancakes);
288280
}
289281
stack.pop();
290282
}
291-
BorrowedCommand::PutTheTopPancakesTogether => {
283+
Command::PutTheTopPancakesTogether => {
292284
if stack.len() < 2 {
293285
return Err(Error::OutOfPancakes);
294286
}
@@ -297,29 +289,29 @@ where
297289
let result = first.checked_add(second).ok_or(Error::PancakeOverflow)?;
298290
stack.push(result);
299291
}
300-
BorrowedCommand::GiveMeAPancake => {
292+
Command::GiveMeAPancake => {
301293
input.read_line(&mut in_line)?;
302294
let number_input = in_line
303295
.parse()
304296
.map_err(|_| Error::InvalidPancake(in_line.clone()))?;
305297
stack.push(number_input);
306298
in_line.clear();
307299
}
308-
BorrowedCommand::HowAboutAHotcake => {
300+
Command::HowAboutAHotcake => {
309301
let buf = input.fill_buf()?;
310-
let number_input = *buf.get(0).unwrap_or(&0);
302+
let number_input = *buf.first().unwrap_or(&0);
311303
input.consume(1);
312304
stack.push(u32::from(number_input));
313305
}
314-
BorrowedCommand::ShowMeAPancake => {
306+
Command::ShowMeAPancake => {
315307
if stack.is_empty() {
316308
return Err(Error::OutOfPancakes);
317309
}
318310
let top = stack.last().unwrap();
319311
let c = char::from_u32(*top).ok_or(Error::CanNotShowPancake(*top))?;
320312
write!(output, "{}", c)?;
321313
}
322-
BorrowedCommand::TakeFromTheTopPancakes => {
314+
Command::TakeFromTheTopPancakes => {
323315
if stack.len() < 2 {
324316
return Err(Error::OutOfPancakes);
325317
}
@@ -328,7 +320,7 @@ where
328320
let result = first.checked_sub(second).ok_or(Error::PancakeUnderflow)?;
329321
stack.push(result);
330322
}
331-
BorrowedCommand::FlipThePancakesOnTop => {
323+
Command::FlipThePancakesOnTop => {
332324
if stack.len() < 2 {
333325
return Err(Error::OutOfPancakes);
334326
}
@@ -337,20 +329,20 @@ where
337329
stack.push(first);
338330
stack.push(second);
339331
}
340-
BorrowedCommand::PutAnotherPancakeOnTop => {
332+
Command::PutAnotherPancakeOnTop => {
341333
if stack.is_empty() {
342334
return Err(Error::OutOfPancakes);
343335
}
344336
stack.push(*stack.last().unwrap());
345337
}
346-
BorrowedCommand::Label(label) => {
338+
Command::Label(label) => {
347339
if stack.is_empty() {
348340
return Err(Error::OutOfPancakes);
349341
}
350342
let top = stack.last().unwrap();
351-
labels.insert(*label, (*top - 1) as usize);
343+
labels.insert(label, (*top - 1) as usize);
352344
}
353-
BorrowedCommand::IfThePancakeIsntTastyGoOverTo(target_label) => {
345+
Command::IfThePancakeIsntTastyGoOverTo(target_label) => {
354346
if stack.is_empty() {
355347
return Err(Error::OutOfPancakes);
356348
}
@@ -362,7 +354,7 @@ where
362354
current_statement = *label_position;
363355
}
364356
}
365-
BorrowedCommand::IfThePancakeIsTastyGoOverTo(target_label) => {
357+
Command::IfThePancakeIsTastyGoOverTo(target_label) => {
366358
if stack.is_empty() {
367359
return Err(Error::OutOfPancakes);
368360
}
@@ -374,31 +366,31 @@ where
374366
current_statement = *label_position;
375367
}
376368
}
377-
BorrowedCommand::PutSyrupOnThePancakes => {
369+
Command::PutSyrupOnThePancakes => {
378370
for value in &mut stack {
379371
*value = value.checked_add(1).ok_or(Error::PancakeOverflow)?;
380372
}
381373
}
382-
BorrowedCommand::PutButterOnThePancakes => {
374+
Command::PutButterOnThePancakes => {
383375
if stack.is_empty() {
384376
return Err(Error::OutOfPancakes);
385377
}
386378
let top = stack.last_mut().unwrap();
387379
*top = top.checked_add(1).ok_or(Error::PancakeOverflow)?;
388380
}
389-
BorrowedCommand::TakeOffTheSyrup => {
381+
Command::TakeOffTheSyrup => {
390382
for value in &mut stack {
391383
*value = value.checked_sub(1).ok_or(Error::PancakeUnderflow)?;
392384
}
393385
}
394-
BorrowedCommand::TakeOffTheButter => {
386+
Command::TakeOffTheButter => {
395387
if stack.is_empty() {
396388
return Err(Error::OutOfPancakes);
397389
}
398390
let top = stack.last_mut().unwrap();
399391
*top = top.checked_sub(1).ok_or(Error::PancakeUnderflow)?;
400392
}
401-
BorrowedCommand::EatAllOfThePancakes => {
393+
Command::EatAllOfThePancakes => {
402394
break;
403395
}
404396
}

src/lib.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -76,24 +76,21 @@
7676
//!
7777
//! **Construct programs**
7878
//!
79-
//! A program can be parsed from a [`str`](https://doc.rust-lang.org/std/str/) with [`pancakestack::run_program_str`](./interpret/fn.run_program_str.html). A single line (=command) can be parsed with [`BorrowedCommand::from_line`](./parse/enum.BorrowedCommand.html#method.from_line).
79+
//! A program can be parsed from a [`str`](https://doc.rust-lang.org/std/str/) with [`pancakestack::run_program_str`](./interpret/fn.run_program_str.html). A single line (=command) can be parsed with [`Command::from_line`](./parse/enum.Command.html#method.from_line).
8080
//!
81-
//! Parsed programs are slices of [`BorrowedCommand`](./parse/enum.BorrowedCommand.html)s and can be run with [`pancakestack::run_program`](./interpret/fn.run_program.html).
81+
//! Parsed programs are slices of [`Command`](./parse/enum.Command.html)s and can be run with [`pancakestack::run_program`](./interpret/fn.run_program.html).
8282
//!
8383
//! ```rust
84-
//! use pancakestack::BorrowedCommand;
84+
//! use pancakestack::Command;
8585
//!
8686
//! let program = [
87-
//! BorrowedCommand::PutThisPancakeOnTop("test"),
88-
//! BorrowedCommand::ShowMeAPancake,
89-
//! BorrowedCommand::EatAllOfThePancakes
87+
//! Command::PutThisPancakeOnTop("test".into()),
88+
//! Command::ShowMeAPancake,
89+
//! Command::EatAllOfThePancakes
9090
//! ];
9191
//! pancakestack::run_program(&program, std::io::stdin(), std::io::stdout()).unwrap();
9292
//!
9393
94-
#[macro_use]
95-
extern crate lazy_static;
96-
9794
pub mod interpret;
9895
pub mod parse;
9996

0 commit comments

Comments
 (0)