first files

This commit is contained in:
rick 2023-04-10 19:43:12 +02:00
commit fb9bfdeda8
Signed by: Rick
GPG key ID: 5CBE8779CD27BCBA
4 changed files with 319 additions and 0 deletions

41
.gitignore vendored Normal file
View file

@ -0,0 +1,41 @@
# Created by https://www.toptal.com/developers/gitignore/api/vim,rust
# Edit at https://www.toptal.com/developers/gitignore?templates=vim,rust
### Rust ###
# Generated by Cargo
# will have compiled files and executables
debug/
target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb
### Vim ###
# Swap
[._]*.s[a-v][a-z]
!*.svg # comment out if you don't need vector files
[._]*.sw[a-p]
[._]s[a-rt-v][a-z]
[._]ss[a-gi-z]
[._]sw[a-p]
# Session
Session.vim
Sessionx.vim
# Temporary
.netrwhist
*~
# Auto-generated tag files
tags
# Persistent undo
[._]*.un~
# End of https://www.toptal.com/developers/gitignore/api/vim,rust

9
Cargo.toml Normal file
View file

@ -0,0 +1,9 @@
[package]
name = "red"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
nom = "7.1.3"

61
src/buffer.rs Normal file
View file

@ -0,0 +1,61 @@
use std::env;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
use std::io;
use nom::bytes::complete::{tag, take_while, take_till};
use nom::character::complete::one_of;
use nom::sequence::Tuple;
use nom::branch::alt;
use nom::error::ErrorKind;
use nom::error::Error;
pub struct Buffer {
has_changed: bool,
buffer: Vec<Result<String, io::Error>>,
current_line: usize,
}
impl Buffer {
pub fn new(buffer: Vec<Result<String, io::Error>>) -> Self {
let tmp = buffer.len().saturating_sub(1);
Self {
has_changed: false,
buffer,
current_line: tmp
}
}
// Return the actual line of the buffer
pub fn act(&self) -> usize {
self.current_line
}
// change la ligne actuelle
pub fn change_act(&mut self, new: usize) {
// TODO check si > len
self.current_line = new;
}
// affiche une ligne
pub fn print_line(&self, nb: usize, print_numbers: bool) {
if nb >= self.buffer.len() {
println!("?");
} else if let Ok(line) = &self.buffer[nb] {
if print_numbers {
println!("{}\t{}", nb + 1, line);
} else {
println!("{}", line);
}
} else {
println!("?");
}
}
// affiche plusieurs lignes
pub fn print_range(&self, first: usize, last: usize, print_numbers: bool) {
for i in first..last {
self.print_line(i, print_numbers);
}
}
}

208
src/main.rs Normal file
View file

@ -0,0 +1,208 @@
mod buffer;
pub use self::buffer::Buffer;
use std::env;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
use std::io;
use nom::bytes::complete::{tag, take_while, take_till};
use nom::character::complete::one_of;
use nom::sequence::Tuple;
use nom::branch::alt;
use nom::error::ErrorKind;
use nom::error::Error;
const FILE : &'static str = "test";
enum Address {
Actual,
Last,
Line(u32),
FromStartTo(u32),
FromToEnd(u32),
FromTo(u32, u32),
Null,
}
enum Command {
Append(Address),
Insert(Address),
Change(Address),
Delete(Address),
// bool pour check ou pas (e et E) TODO mettre le chemin vers le fichier
Edit(bool),
// TODO chemin vers fichier
File(),
// TODO
Help,
// TODO
SetHelp,
Join(Address),
// TODO nom de la marque
Mark(Address),
List(Address),
// TODO
Move(Address),
Number(Address),
Print(Address),
Prompt,
// bool pour check ou pas (q et Q)
Quit(bool),
// TODO
Read,
// TODO
Substitute,
// TODO
CopyLines,
Undo,
// TODO
Write,
// TODO
Line,
// TODO
ShellCommand,
// TODO
Null,
// TODO
Global,
// TODO
NonMatched,
}
/*
* .
* $
* [:digit:]
* '[:alpha:]
* /BRE/
* +[:digit:]
* -[:digit:]
* [:digit:],[:digit:]
* [:digit:];[:digit:]
*/
// TODO juste $ pour l'instant dans l'adresse
// TODO faire les commandes mais juste p pour l'instant
/*
fn read_address(input: &str) -> Result<&str, Address> {
}
*/
/*
* Le char doit être une commande valide.
*/
fn parse_without_addr(c: char) -> Command {
Command::Help
}
fn parse_with_addr(c: char, addr: Address) -> Command {
match c {
'p' => Command::Print(addr),
'n' => Command::Number(addr),
_ => Command::Help,
}
}
fn parse_command(c: char, addr: Option<Address>) -> Command {
if let Some(a) = addr {
parse_with_addr(c, a)
} else {
parse_without_addr(c)
}
}
/*
fn parse_multi_addr(addr: &str) -> Address {
//let extract = take_till::<&str, &str, Error>(|c| c == ',');
let extract = take_till::<&str, &str, Error<&str>>(|c| c != ",");
if let Ok((still, before)) = extract(addr) {
if let Ok((still, after)) = extract(addr) {
}
}
Address::Null
}
*/
fn parse_address(addr: &str) -> Address {
let mut tmp = String::from(addr);
tmp.retain(|c| c != ' ');
let addr = tmp.as_str();
if addr.is_empty() {
Address::Actual
} else {
match addr {
"." => Address::Actual,
"$" => Address::Last,
_ => Address::Null,
}
}
}
fn check_address(c: char) -> bool {
c.is_digit(10) || c == '$' || c == ' ' || c == '.'
}
fn check_address_complete(c: char) -> bool {
check_address(c) || c == ','
}
fn print(buffer: Buffer, addr: Address, print_numbers: bool) {
match addr {
Address::Actual => buffer.print_line(buffer.act(), print_numbers),
Address::Null => println!("nul !"),
_ => println!("coucou2"),
}
}
fn execute_command(buffer: Buffer, c: Command) {
match c {
Command::Print(a) => print(buffer, a, false),
Command::Number(a) => print(buffer, a, true),
_ => println!("coucou"),
}
}
fn parse_line(input: &str) -> Result<Command, String> {
let address = take_while(check_address_complete);
let command = one_of::<_, _, (&str, ErrorKind)>("pn");
//if let Ok((input, (a, c))) = alt(address, command).parse(input) {
if let Ok((input, (a, c))) = (address, command).parse(input) {
//println!("{:?} - {:?} - {:?}", input, a, c);
let addr = parse_address(a);
Ok(parse_command(c, Some(addr)))
} else {
Err(String::from("bruh moment"))
}
}
fn main() {
let buffer : Vec<Result<String, io::Error>> = if let Ok(f) = File::open(FILE) {
let buff = BufReader::new(f);
buff.lines().collect()
} else {
panic!("Le fichier n'existe pas.");
};
let buffer_struct = Buffer::new(buffer);
println!("fichier lu !");
let mut input = String::new();
match io::stdin().read_line(&mut input) {
Ok(n) => {
if let Ok(c) = parse_line(&input) {
execute_command(buffer_struct, c);
} else {
println!("coucou");
}
},
Err(e) => println!("error"),
}
}