summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Cargo.toml8
-rw-r--r--src/main.rs35
-rw-r--r--src/parser.rs91
4 files changed, 135 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..9d07f78
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "progcalc"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..d4e9cac
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,35 @@
+
+
+#[derive(Debug)]
+enum BaseNumber {
+ Decimal(i64),
+ Octal(i64),
+ Binary(i64),
+ Hexadecimal(i64),
+ Nan,
+}
+
+impl BaseNumber {
+ fn format(&self) -> Result<String, String> {
+ match self {
+ Self::Binary(value) => Ok(format!("{:b}", value)),
+ Self::Octal(value) => Ok(format!("{:o}", value)),
+ Self::Decimal(value) => Ok(format!("{}", value)),
+ Self::Hexadecimal(value) => Ok(format!("{:x}", value)),
+ Nan => Err("Not a number!".to_string()),
+ }
+ }
+}
+
+#[derive(Debug)]
+enum Operator {
+ Add,
+ Sub,
+ Mul,
+ Div,
+}
+
+fn main() {
+ println!("Hello, world!");
+ println!("{}", numformat(15, 16).unwrap());
+}
diff --git a/src/parser.rs b/src/parser.rs
new file mode 100644
index 0000000..fe414b0
--- /dev/null
+++ b/src/parser.rs
@@ -0,0 +1,91 @@
+extern crate core;
+use core::str::Chars;
+
+#[derive(Debug, PartialEq)]
+pub enum Token {
+ Number(i32),
+ Plus,
+ Minus,
+ Multiply,
+ Divide,
+}
+
+pub struct Lexer<'a> {
+ chars: Chars<'a>,
+}
+
+impl<'a> Lexer<'a> {
+ // Constructor
+ pub fn new(input: &'a str) -> Self {
+ Lexer { chars: input.chars() }
+}
+
+ fn next_token(&mut self) -> Option<Token> {
+ let next_char = self.chars.next()?;
+
+ match next_char {
+ '+' => Some(Token::Plus),
+ '-' => Some(Token::Minus),
+ '*' => Some(Token::Multiply),
+ '/' => Some(Token::Divide),
+ '1'..='9' => {
+ let mut number = next_char.to_digit(10)? as i32;
+ while let Some(next_char) = self.chars.clone().next() {
+ if let Some(digit) = next_char.to_digit(10) {
+ number = number * 10 + digit as i32;
+ self.chars.next();
+ } else {
+ break;
+ }
+ }
+ Some(Token::Number(number))
+ }
+ '0' => {
+ let base = match self.chars.next().unwrap() {
+ 'b' => Some(2),
+ 'o' => Some(8),
+ 'x' => Some(16),
+ _ => None,
+ };
+ if base.is_none() {
+ return None;
+ }
+
+ let mut number = next_char.to_digit(base.clone().unwrap())?;
+ while let Some(next_char) = self.chars.clone().next() {
+ if let Some(digit) = next_char.to_digit(base.clone().unwrap()) {
+ number = number * base.clone().unwrap() + digit;
+ self.chars.next();
+ } else {
+ break;
+ }
+ }
+ Some(Token::Number(number as i32))
+ }
+ _ => None,
+ }
+ }
+
+ pub fn tokenize(&mut self) -> Vec<Token> {
+ let mut tokens = Vec::new();
+ while let Some(token) = self.next_token() {
+ tokens.push(token);
+ }
+ tokens
+ }
+}
+
+fn main() {
+ let mut lexer = Lexer::new("0x6A+0b001101*0o13");
+ let tokens = lexer.tokenize();
+ assert_eq!(
+ tokens,
+ vec![
+ Token::Number(106),
+ Token::Plus,
+ Token::Number(13),
+ Token::Multiply,
+ Token::Number(11),
+ ]
+ );
+} \ No newline at end of file