made a graphing calculator

idk why
This commit is contained in:
FantasyPvP
2023-10-03 00:43:20 +01:00
parent 410278b6e3
commit e92e01c5b8
13 changed files with 367 additions and 29 deletions
+1
View File
@@ -0,0 +1 @@
{}
+3
View File
@@ -0,0 +1,3 @@
{
"accentColor": ""
}
+30
View File
@@ -0,0 +1,30 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": true,
"backlink": true,
"canvas": true,
"outgoing-link": true,
"tag-pane": true,
"properties": false,
"page-preview": true,
"daily-notes": true,
"templates": true,
"note-composer": true,
"command-palette": true,
"slash-command": false,
"editor-status": true,
"bookmarks": true,
"markdown-importer": false,
"zk-prefixer": false,
"random-note": false,
"outline": true,
"word-count": true,
"slides": false,
"audio-recorder": false,
"workspaces": false,
"file-recovery": true,
"publish": false,
"sync": false
}
+20
View File
@@ -0,0 +1,20 @@
[
"file-explorer",
"global-search",
"switcher",
"graph",
"backlink",
"canvas",
"outgoing-link",
"tag-pane",
"page-preview",
"daily-notes",
"templates",
"note-composer",
"command-palette",
"editor-status",
"bookmarks",
"outline",
"word-count",
"file-recovery"
]
+1
View File
@@ -0,0 +1 @@
{}
+166
View File
@@ -0,0 +1,166 @@
{
"main": {
"id": "b036f596c3d87102",
"type": "split",
"children": [
{
"id": "181ea72dff424a18",
"type": "tabs",
"children": [
{
"id": "66a91bbf10023e7b",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "docs/crystal-api.md",
"mode": "source",
"source": false
}
}
}
]
}
],
"direction": "vertical"
},
"left": {
"id": "da47277ea99884ad",
"type": "split",
"children": [
{
"id": "cd2adc39ca215cb7",
"type": "tabs",
"children": [
{
"id": "b99370e56eef957e",
"type": "leaf",
"state": {
"type": "file-explorer",
"state": {
"sortOrder": "alphabetical"
}
}
},
{
"id": "d3bad314da2e86db",
"type": "leaf",
"state": {
"type": "search",
"state": {
"query": "",
"matchingCase": false,
"explainSearch": false,
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical"
}
}
},
{
"id": "b6369321de815c85",
"type": "leaf",
"state": {
"type": "bookmarks",
"state": {}
}
}
]
}
],
"direction": "horizontal",
"width": 300
},
"right": {
"id": "cc77998b0fe66c78",
"type": "split",
"children": [
{
"id": "539d4acb3fd37c0d",
"type": "tabs",
"children": [
{
"id": "80a0f5c3389bff71",
"type": "leaf",
"state": {
"type": "backlink",
"state": {
"file": "docs/crystal-api.md",
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical",
"showSearch": false,
"searchQuery": "",
"backlinkCollapsed": false,
"unlinkedCollapsed": true
}
}
},
{
"id": "22b681b84ff588cb",
"type": "leaf",
"state": {
"type": "outgoing-link",
"state": {
"file": "docs/crystal-api.md",
"linksCollapsed": false,
"unlinkedCollapsed": true
}
}
},
{
"id": "9b7726f31b8f3647",
"type": "leaf",
"state": {
"type": "tag",
"state": {
"sortOrder": "frequency",
"useHierarchy": true
}
}
},
{
"id": "4bde4e08b234e5b9",
"type": "leaf",
"state": {
"type": "outline",
"state": {
"file": "docs/crystal-api.md"
}
}
}
]
}
],
"direction": "horizontal",
"width": 300,
"collapsed": true
},
"left-ribbon": {
"hiddenItems": {
"switcher:Open quick switcher": false,
"graph:Open graph view": false,
"canvas:Create new canvas": false,
"daily-notes:Open today's daily note": false,
"templates:Insert template": false,
"command-palette:Open command palette": false
}
},
"active": "66a91bbf10023e7b",
"lastOpenFiles": [
"target/x86_64-CrystalOS/debug/bootimage-CrystalOS.bin.temp-stream-669ebd",
"target/x86_64-CrystalOS/debug/bootimage-CrystalOS.bin.temp-stream-9e0e9c",
"target/x86_64-CrystalOS/debug/bootimage-CrystalOS.bin.temp-stream-d5e1e2",
"target/x86_64-CrystalOS/debug/incremental/CrystalOS-2s2eto1gmy107/s-gpa8tfuu7j-zjn7o7-au49h4b9abxljhlinnweh4wh/zypku2ljqkwe2t9.o",
"target/x86_64-CrystalOS/debug/incremental/CrystalOS-2s2eto1gmy107/s-gpa8tfuu7j-zjn7o7-au49h4b9abxljhlinnweh4wh/x6aoth2ydi59hrm.o",
"target/x86_64-CrystalOS/debug/incremental/CrystalOS-2s2eto1gmy107/s-gpa8tfuu7j-zjn7o7-au49h4b9abxljhlinnweh4wh/work-products.bin",
"target/x86_64-CrystalOS/debug/incremental/CrystalOS-2s2eto1gmy107/s-gpa8tfuu7j-zjn7o7-au49h4b9abxljhlinnweh4wh/wl6c5klbro0lehu.o",
"target/x86_64-CrystalOS/debug/incremental/CrystalOS-2s2eto1gmy107/s-gpa8tfuu7j-zjn7o7-au49h4b9abxljhlinnweh4wh/vrj0gel9n5vxmd1.o",
"target/x86_64-CrystalOS/debug/incremental/CrystalOS-2s2eto1gmy107/s-gpa8tfuu7j-zjn7o7-au49h4b9abxljhlinnweh4wh/uoqvrm3l2w095ln.o",
"target/x86_64-CrystalOS/debug/incremental/CrystalOS-2s2eto1gmy107/s-gpa8tfuu7j-zjn7o7-au49h4b9abxljhlinnweh4wh/uhkf8uzx25q6zkn.o",
"target/x86_64-CrystalOS/debug/incremental/CrystalOS-2s2eto1gmy107/s-gpa8tfuu7j-zjn7o7-au49h4b9abxljhlinnweh4wh/query-cache.bin",
"docs/main.md",
"README.md",
"docs/crystal-api.md"
]
}
Generated
+21
View File
@@ -27,6 +27,7 @@ dependencies = [
"spin",
"uart_16550",
"uchan",
"vga",
"volatile 0.2.7",
"x86_64",
]
@@ -179,6 +180,12 @@ dependencies = [
"num",
]
[[package]]
name = "font8x8"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "875488b8711a968268c7cf5d139578713097ca4635a76044e8fe8eedf831d07e"
[[package]]
name = "futures-core"
version = "0.3.28"
@@ -473,6 +480,20 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "vga"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5dd163a9cf938e0406e1ee29e3b71ac7d8f5ffe6c1321fe74797ebef1299bc6"
dependencies = [
"bitflags 1.3.2",
"conquer-once",
"font8x8",
"num-traits",
"spinning_top",
"x86_64",
]
[[package]]
name = "volatile"
version = "0.2.7"
+1
View File
@@ -32,6 +32,7 @@ libm = "0.2.7"
log = "0.4.20"
uchan = { version = "0.1.4", default-features = false }
embedded-time = "0.12.1"
vga = "0.2.9"
[dependencies.lazy_static]
version = "1.0"
+13 -28
View File
@@ -10,33 +10,20 @@ with the github repo for his project here:
https://github.com/phil-opp/blog_os
After reading and implementing the features from the final chapter, (async/await) I could find
no further instruction on how to continue with the project from there despite the author of the
series saying over a year previously that there would be more posts coming soon.
After reading and implementing the features from the final chapter, (async/await) I could find no further instruction on how to continue with the project from there despite the author of the series saying over a year previously that there would be more posts coming soon.
i guess im gonna just have to improvise :)
while I'm waiting for the third edition to release, I guess I'm gonna just have to improvise :)
the blog got me through the memory management side of the process so i believe that I should
have a lot more breathing room to implement the features that i want. As of completing the
tutorial, i obviously still dont have access to a standard library, however i can at least
use Vectors and Strings now which are important types, as well as the fact that i have access
to async and heap allocation
the blog got me through the memory management side of the process so i believe that I should have a lot more breathing room to implement the features that i want. As of completing the tutorial, i obviously still dont have access to a standard library, however i can at least use Vectors and Strings now which are important types, as well as the fact that i have access to async and heap allocation.
### my aims going forwards:
- whenever i have the chance to work on this project, i want to try and implement a new utility
which could be useful or cool for anyone using the operating system.
- this could be anything from a cool neofetch style ascii fetcher (if you dont know what im
talking about, its just a cool ascii logo of the operating system that appears when you open
a terminal sometimes)
- improve the text rendering system to create a set of globally accessible functions and/or macros
in order to render the text in a more visually appealing way to the user (as the default yellow text
does look extremely ugly lmao)
- whenever i have the chance to work on this project, i want to try and implement a new utility which could be useful or cool for anyone using the operating system.
- this could be anything from a cool neofetch style ascii fetcher (if you dont know what im talking about, its just a cool ascii logo of the operating system that appears when you open a terminal sometimes)
- improve the text rendering system to create a set of globally accessible functions and/or macros in order to render the text in a more visually appealing way to the user (as the default yellow text does look extremely ugly lmao)
- implement a basic text editor (this will be difficult)
- i would need a way to move the cursor around the screen and print text at that location
- this would mean rewriting the majority of the code for the vga buffer module to create a more
flexible system which allows for applications (modules / commands) to take more direct control of
the text rendering whenever they are active
- this would mean rewriting the majority of the code for the vga buffer module to create a more flexible system which allows for applications (modules / commands) to take more direct control of the text rendering whenever they are active
# Implementation
@@ -47,17 +34,14 @@ does look extremely ugly lmao)
diverging from the original blog series, i have made some significant changes to keyboard.rs
- i have moved the source code that handles the keyboard input from keyboard.rs to shell.rs
- this means that instead of the operating system running a task on startup that continually
awaits a the next keystroke and works from there, the new layout works very differently
- this means that instead of the operating system running a task on startup that continually awaits a the next keystroke and works from there, the new layout works very differently
- firstly, i use a lazy_static creating a static called CMD which houses the shell itself
- this allows me to reference it from anywhere in the code and initialise it as soon as the program
runs
- this allows me to reference it from anywhere in the code and initialise it as soon as the program runs
- this may be changed later as i could just make an init function in shell.rs if i needed to
- the shell contains a get_input function that awaits a keystroke from the user before continuing
- this is looped inside the main shell function and added to a buffer
- when the \n character is inputted, the buffer is copied to the command history vector and then cleared
- additionally the buffer is run through a match statement that will start any app that matches the command
or alias.
- additionally the buffer is run through a match statement that will start any app that matches the command or alias.
## Phase 3: CrystalAPI
@@ -65,8 +49,7 @@ or alias.
the crystal api will essentially be a standard library for any programs that are run by the shell
- it provides basic functions such as waiting for a keystroke or string to be entered by the user
- it will eventually support coloured text output once ive had a chance to modify the code for the vga
buffer to support coloured text output through a public function.
- it will eventually support coloured text output once ive had a chance to modify the code for the vga buffer to support coloured text output through a public function.
### example:
here is a template that could be used to program using the crystal API
@@ -214,3 +197,5 @@ over the last couple of days I've made some signifcant changes to this project.
I have started the development of a TUI (terminal user interface) library allowing for widgets to be displayed
on screen using ascii.
its pretty barebones at the moment but I'm hoping to add more features as time goes on!
## UPDATE: 02/10/23
+21 -1
View File
@@ -403,15 +403,18 @@ impl Application for Calculator {
return Err(ShellError::CommandFailed(String::from("failed")))
},
};
Ok(())
}
}
}
pub fn calc_outer(mut equation: String) -> Result<f64, String> {
calculate_inner2(equation).map_err(|_| String::from("failed to calculate"))
}
fn calculate_inner(mut equation: String) -> Result<f64, Error> {
equation.push('\n');
let mut neweq = equation.clone();
neweq.pop();
@@ -439,6 +442,23 @@ fn calculate_inner(mut equation: String) -> Result<f64, Error> {
Ok(return_res)
}
fn calculate_inner2(mut equation: String) -> Result<f64, Error> {
equation.push('\n');
let mut neweq = equation.clone();
neweq.pop();
let tokens = tokenise(&equation)?;
let mut parser = Parser::new(tokens)?;
let ast = parser.parse()?;
let mut interpreter = Interpreter::new()?;
let result = interpreter.visit(ast)?;
let return_res = if let Value::Number(x) = result {
x
} else { panic!("the value returned was not a float! THIS IS A BUG") };
Ok(return_res)
}
+74
View File
@@ -0,0 +1,74 @@
use alloc::string::{String, ToString};
use alloc::vec;
use alloc::vec::Vec;
use alloc::boxed::Box;
use async_trait::async_trait;
use crate::println;
use crate::shell::command_handler;
use crate::std::application::{Application, Error};
use crate::std::frame::Element;
use crate::std::io::{Screen, Stdin};
pub struct Grapher {
points: Vec<Point>,
}
struct Point {
x: i16,
y: i16,
}
#[async_trait]
impl Application for Grapher {
fn new() -> Self {
Self {
points: Vec::new(),
}
}
async fn run(&mut self, args: Vec<String>) -> Result<(), Error> {
let mut equation: String = args.into_iter().collect();
use super::calc;
for x in -40..40 {
let new_eq = equation.chars().map(|c| {
if c == 'x' { x.to_string() } else { c.to_string() }
}).collect::<String>();
let y = calc::calc_outer(new_eq).map_err(|_| Error::ApplicationError(String::from("failed to calculate")))?;
self.points.push(Point {
x,
y: y as i16,
})
};
Screen::application_mode();
self.render();
loop {
match Stdin::keystroke().await {
'x' => break,
_ => continue,
}
}
Screen::terminal_mode();
Ok(())
}
}
impl Grapher {
fn render(&self) {
let mut frame: Vec<Vec<char>> = vec![vec![' '; 80]; 25];
self.points.iter().filter(|i| i.x >= -40 && i.x < 40 && i.y >= -12 && i.y <= 12).for_each(|i| {
let offset_x = i.x + 40;
let offset_y = i.y + 12;
//println!("{} {}", i.x, i.y);
frame[24-offset_y as usize][offset_x as usize] = '*';
});
let mut elem = Element::generate(frame, (80, 25));
elem.render((0, 0));
}
}
+1
View File
@@ -8,3 +8,4 @@ pub mod tasks;
mod gigachad_detector;
//mod shellrewrite;
mod snake;
mod grapher;
+15
View File
@@ -8,6 +8,7 @@ use alloc::{
string::{String, ToString},
vec::Vec,
};
use vga::writers::{GraphicsWriter, PrimitiveDrawing};
use crate::{
print, println,
@@ -16,6 +17,7 @@ use crate::{
};
use crate::std::io::{Color, write, Screen};
use crate::user::bin::gigachad_detector::GigachadDetector;
use crate::user::bin::grapher::Grapher;
lazy_static! {
pub static ref CMD: Mutex<CommandHandler> = Mutex::new(CommandHandler::new());
@@ -97,6 +99,19 @@ async fn exec() -> Result<(), Error> {
let mut gameloop = crystal_rpg::init::GameLoop::new();
gameloop.run(args).await?;
}
"VGA" => {
use vga::colors::Color16;
use vga::writers::{GraphicsWriter, Graphics640x480x16};
let mode = Graphics640x480x16::new();
mode.set_mode();
mode.clear_screen(Color16::Black);
mode.draw_line((80, 60), (80, 420), Color16::Cyan);
}
"graph" => {
let mut grapher = Grapher::new();
grapher.run(args).await?;
}
// direct OS functions (not applications)
"echo" => {