Merge branch 'master' into c-build-module

This commit is contained in:
Kyler Olsen 2025-12-13 22:31:52 -07:00
commit 4fa7321567
14 changed files with 281 additions and 74 deletions

View File

@ -1,6 +1,69 @@
# SE 3250 Progress Checkpoints # SLS Changelog
## Checkpoint 3 ## 0.0.2-alpha
*08 Dec 2025*
- Added Rust Port
- Added Interpreter State Serialization to Rust port
- Added `#load <file>` and `#save <file>` directives to the REPL
- Added Python Port
- Added Calculator app
- Added sls_py.calc module
- Added RP2040 build target for the C implementation
## 0.0.1-alpha
*01 Dec 2025*
- Added executing a file
- Implemented the following builtin operators:
- `for`
- `logb`
- `max`
- `min`
- `rot`
- `const`
- `atan2`
- `roll`
- `while`
- `type_of`
- `eval`
- `lambda`
- `if`
- `pick`
- `dup`
- bitwise `and`
- bitwise `not`
- bitwise `or`
- bitwise `xor`
- boolean `and`
- boolean `not`
- boolean `or`
- `shl`
- `shr`
- comparisons
- `ceil`
- `floor`
- `round`
- `swap`
- `seed`
- `rand`
- `acos`
- `asin`
- `atan`
- `cos`
- `ln`
- `log`
- `sin`
- `sqrt`
- `tan`
- `abs`
- modulus
- exponential
- addition
- subtraction
- multiplication
## SE Checkpoint 3
*28 Nov 2025* *28 Nov 2025*
[github.com/SnowSE/final-project-KylerOlsen](https://github.com/SnowSE/final-project-KylerOlsen) [github.com/SnowSE/final-project-KylerOlsen](https://github.com/SnowSE/final-project-KylerOlsen)
@ -28,7 +91,7 @@ I'm not really stuck on anything, but I am running out of time, plus I am
worried about not having enough AI usage to do the ports. If I at least get the worried about not having enough AI usage to do the ports. If I at least get the
main structures of the ports, I hope it will be enough for me to finish. main structures of the ports, I hope it will be enough for me to finish.
## Checkpoint 2 ## SE Checkpoint 2
*20 Nov 2025* *20 Nov 2025*
[github.com/SnowSE/final-project-KylerOlsen](https://github.com/SnowSE/final-project-KylerOlsen) [github.com/SnowSE/final-project-KylerOlsen](https://github.com/SnowSE/final-project-KylerOlsen)
@ -58,7 +121,7 @@ features moved to the backlog include:
- Type tuples, function defs - Type tuples, function defs
- Structs, unions, etc. - Structs, unions, etc.
## Checkpoint 1 ## SE Checkpoint 1
*07 Nov 2025* *07 Nov 2025*
**intended user**: **intended user**:

123
README.md
View File

@ -1,9 +1,128 @@
# YREA SLS # YREA SLS
*Kyler Olsen* *Kyler Olsen*
*October 2025* *October 2025*
*Snow College*
*SE 3250 Survey of Languages Final Project*
SLS is a statically-typed, stack-based language with pure postfix notation SLS is a statically-typed, stack-based language with pure postfix notation
combining the execution model of HP's RPL, the type system of C and Rust, and combining the execution model of HP's RPL, the type system of C and Rust, and
modern array operations from Uiua. modern array operations from Uiua.
## Build Commands
**Linux**
C
```bash
cd SLS_C
python3 build.py build
./bin/sls
```
Python run module
```bash
cd SLS_Python
python3 -m sls_py
python3 -m sls_py.calc
```
Python Setup
```bash
cd SLS_Python
python -m venv .venv
source .venv/bin/activate
pip install build wheel "setuptools>=61.0"
pip install -e sls_build_backend
```
Python build module
```bash
cd SLS_Python
source .venv/bin/activate
python3 -m build --no-isolation
pip install ./dist/sls_python-0.0.2a0-py3-none-any.whl
python3 -m sls_py
python3 -m sls_py.calc
```
Rust
```bash
cd SLS_Rust/sls
cargo build
./target/debug/sls_rs
```
**Windows**
C (Using Visual Studio Developer PowerShell)
```shell
cd SLS_C
python build.py build
.\bin\sls.exe
```
Python run module
```bat
cd SLS_Python
python -m sls_py
python -m sls_py.calc
```
Python Setup
```bat
cd SLS_Python
python -m venv .venv
.venv\Scripts\activate.bat
pip install build wheel "setuptools>=61.0"
pip install -e sls_build_backend
```
Python build module
```bat
cd SLS_Python
.venv\Scripts\activate.bat
python -m build --no-isolation
pip install .\dist\sls_python-0.0.2a0-py3-none-any.whl
python -m sls_py
python -m sls_py.calc
```
Rust
```bat
cd SLS_Rust\sls
cargo build
.\target\debug\sls_rs.exe
```
**MacOS**
Reference Linux build instructions.
For C there is the `python3 build.py macos` command, but it is untested as I
didn't test it on a Mac. I also don't know if `python3 build.py build` would also
work on a Mac.
Python and Rust should just be the same or similar to Linux.
**RP2040**
Only tested on Linux. Only SLS_C supports RP2040.
Install Pico SDK to `~/pico/pico-sdk`, or set environment variable
`PICO_SDK_PATH` to your installation path. You will also need to install the
appropriate compiler.
Debian GNU/Linux
```bash
sudo apt install gcc-arm-none-eabi
```
```shell
cd SLS_C
python3 build.py rp2040
```
Flash Raspberry Pi Pico:
Copy `.\build_pico\sls.elf.uf2` to your Pico in BOOTSEL mode
## Contributing
[sls.purplecello.org/contributing](https://sls.purplecello.org/contributing.html)

View File

@ -2,7 +2,9 @@
*Kyler Olsen* *Kyler Olsen*
*October-December 2025* *October-December 2025*
*Snow College* *Snow College*
*SE 3250 Survey of Languages Final Project* *SE 3250*
*Survey of Languages*
*Final Project*
Language Code Name: Language Code Name:
YREA **SLS** (*Stack Language Specification*) YREA **SLS** (*Stack Language Specification*)
@ -17,8 +19,6 @@ Language Implementation Repository (Mirror on GitHub) (Private):
Assignment Page (Private): Assignment Page (Private):
[snow.instructure.com](https://snow.instructure.com/courses/1154808/assignments/16233203) [snow.instructure.com](https://snow.instructure.com/courses/1154808/assignments/16233203)
## Problem and Interest
In 1986, Hewlett-Packard released their HP-18C and HP-24C calculators, which In 1986, Hewlett-Packard released their HP-18C and HP-24C calculators, which
introduced their new RPL operating system and programming language. The language introduced their new RPL operating system and programming language. The language
was based on LISP and Forth (a stack-oriented language). RPL, aka Reverse Polish was based on LISP and Forth (a stack-oriented language). RPL, aka Reverse Polish
@ -41,14 +41,25 @@ follows the pattern in RPL, everything is on the stack. One of my goals with
this language is also to have it able to run on an embedded system, such as my this language is also to have it able to run on an embedded system, such as my
own custom calculator. own custom calculator.
## Languages
**C** was my selected language. It was an excellent choice for my project as it **C** was my selected language. It was an excellent choice for my project as it
is well suited for systems programming. It is a low level, yet powerful is well suited for systems programming. It is a low level, yet powerful
language. While string utilities are not as robust as most modern languages, I language. While string utilities are not as robust as most modern languages, I
still feel like it was an excellent choice. Other major interpreted languages still feel like it was an excellent choice. Other major interpreted languages
also use C to implement their interpreters, such as Lua and Python. also use C to implement their interpreters, such as Lua and Python.
Manual memory management was a slight difficulty for me. The only way I could
find what was causing a segmentation fault was to run the binary with `gdb`.
Still my experience programming C in a Linux environment was fun and rewarding.
I became accustomed to utilizing the man pages (or manual pages) for
documentation on the C standard library.
I did use structs and unions heavily which we learned about when we looked at C.
With them I was able to use polymorphism in defining tokens and data types.
I am able to successfully compile and run this implementation on a Raspberry Pi
Pico with a RP2040 microcontroller. You can interact with the REPL over a serial
connection.
**Rust** was the first language I tackled porting my project to. I am not as **Rust** was the first language I tackled porting my project to. I am not as
familiar with Rust as I am Python, so thats why I wanted to get going on this familiar with Rust as I am Python, so thats why I wanted to get going on this
port first. I avoided using external libraries with C as they can be famously port first. I avoided using external libraries with C as they can be famously
@ -57,6 +68,10 @@ basically non-existent. It is also memory safe with its barrow checker. With it
being another systems programming language, and these modern features, I feel being another systems programming language, and these modern features, I feel
like it is just as good of a choice of a language for my project. like it is just as good of a choice of a language for my project.
In the past I have often fought with the barrow checker but with this project,
either my experience, memory mindfulness in my original port, or the extensive
AI help, I had no fights with the barrow checker this time.
The special feature for the Rust port is being able to export and import the The special feature for the Rust port is being able to export and import the
interpreter state in the repl using `#save <filename>` and `#load <filename>`. interpreter state in the repl using `#save <filename>` and `#load <filename>`.
@ -70,17 +85,8 @@ goal of portability to embedded systems.
The special feature for the Python port is the SLS Calculator App. The special feature for the Python port is the SLS Calculator App.
## Lessons
## Struggles
In the past I have often fought with the barrow checker but with this project,
either my experience, memory mindfulness in my original port, or the extensive
AI help, I had no fights with the barrow checker this time.
--- ---
https://en.wikipedia.org/wiki/HP_48_series https://en.wikipedia.org/wiki/HP_48_series
https://en.wikipedia.org/wiki/HP-28_series https://en.wikipedia.org/wiki/HP-28_series
https://en.wikipedia.org/wiki/RPL_(programming_language) https://en.wikipedia.org/wiki/RPL_(programming_language)
https://gitlab.com/da_doomer/markdown-slides

1
SLS_C/fib.min.sls Normal file
View File

@ -0,0 +1 @@
{ 2 - dup 0 <= { drop 1 } { 1 1 rot 0 swap { drop swap 1 pick + } for swap drop } if } lambda ::fib const

17
SLS_C/fib.sls Normal file
View File

@ -0,0 +1,17 @@
{
// Start with which Fibonacci number we want (Nth Fibonacci number)
2 - // We push the first two already
dup 0 <= { drop 1 } {
1 1 // Starting Fibonacci numbers
rot 0 swap // Setting up loop from zero to N
{
drop // Discard the loop counter
swap 1 pick // Swap n-1 and n-2 and copy n-1
+ // Add n-2 and the copy of n-1
// n and n-1 left on stack
} for
swap drop // Drop n-1 from the stack
} if
} lambda ::fib const
8 fib

View File

@ -7,7 +7,7 @@
#define SLS_MAIN_H #define SLS_MAIN_H
#define SLS_NAME "SLS_C" #define SLS_NAME "SLS_C"
#define SLS_VER "0.0.1-alpha" #define SLS_VER "0.0.2-alpha"
#ifndef GIT_COMMIT_HASH #ifndef GIT_COMMIT_HASH
#define GIT_COMMIT_HASH "UNKNOWN" #define GIT_COMMIT_HASH "UNKNOWN"

View File

@ -1803,8 +1803,8 @@ static TestResult test_Float_f32_Negative_Zero() {
return pass_test(&test, result); return pass_test(&test, result);
} }
static TestResult test_Char_Simple_Letter_A() { static TestResult test_Char_Simple_Letter_Uppercase_A() {
LexerTest test = start_up_test(SLS_STR("Char Simple Letter A"), SLS_STR("'A'")); LexerTest test = start_up_test(SLS_STR("Char Simple Letter Uppercase A"), SLS_STR("'A'"));
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0; size_t i = 0;
@ -1813,8 +1813,8 @@ static TestResult test_Char_Simple_Letter_A() {
return pass_test(&test, result); return pass_test(&test, result);
} }
static TestResult test_Char_Simple_Letter_a() { static TestResult test_Char_Simple_Letter_Lowercase_a() {
LexerTest test = start_up_test(SLS_STR("Char Simple Letter a"), SLS_STR("'a'")); LexerTest test = start_up_test(SLS_STR("Char Simple Letter Lowercase a"), SLS_STR("'a'"));
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0; size_t i = 0;
@ -1823,8 +1823,8 @@ static TestResult test_Char_Simple_Letter_a() {
return pass_test(&test, result); return pass_test(&test, result);
} }
static TestResult test_Char_Simple_Letter_Z() { static TestResult test_Char_Simple_Letter_Uppercase_Z() {
LexerTest test = start_up_test(SLS_STR("Char Simple Letter Z"), SLS_STR("'Z'")); LexerTest test = start_up_test(SLS_STR("Char Simple Letter Uppercase Z"), SLS_STR("'Z'"));
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0; size_t i = 0;
@ -1833,8 +1833,8 @@ static TestResult test_Char_Simple_Letter_Z() {
return pass_test(&test, result); return pass_test(&test, result);
} }
static TestResult test_Char_Simple_Letter_z() { static TestResult test_Char_Simple_Letter_Lowercase_z() {
LexerTest test = start_up_test(SLS_STR("Char Simple Letter z"), SLS_STR("'z'")); LexerTest test = start_up_test(SLS_STR("Char Simple Letter Lowercase z"), SLS_STR("'z'"));
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0; size_t i = 0;
@ -2073,22 +2073,22 @@ static TestResult test_Char_Right_Brace() {
return pass_test(&test, result); return pass_test(&test, result);
} }
static TestResult test_Char_Escape_Tab() { static TestResult test_Char_Escape_Single_quote() {
LexerTest test = start_up_test(SLS_STR("Char Escape Tab"), SLS_STR("'\\t'")); LexerTest test = start_up_test(SLS_STR("Char Escape Single quote"), SLS_STR("'\\''"));
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0; size_t i = 0;
if (test_character_value(&test, result, i++, &(uint8_t){9})) return test.result; if (test_character_value(&test, result, i++, &(uint8_t){39})) return test.result;
if (test_eof_value(&test, result, i++, 0)) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result;
return pass_test(&test, result); return pass_test(&test, result);
} }
static TestResult test_Char_Escape_Backslash() { static TestResult test_Char_Escape_Newline() {
LexerTest test = start_up_test(SLS_STR("Char Escape Backslash"), SLS_STR("'\\\\'")); LexerTest test = start_up_test(SLS_STR("Char Escape Newline"), SLS_STR("'\\n'"));
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0; size_t i = 0;
if (test_character_value(&test, result, i++, &(uint8_t){92})) return test.result; if (test_character_value(&test, result, i++, &(uint8_t){10})) return test.result;
if (test_eof_value(&test, result, i++, 0)) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result;
return pass_test(&test, result); return pass_test(&test, result);
} }
@ -2103,12 +2103,22 @@ static TestResult test_Char_Escape_Null_character() {
return pass_test(&test, result); return pass_test(&test, result);
} }
static TestResult test_Char_Escape_Single_quote() { static TestResult test_Char_Escape_Backslash() {
LexerTest test = start_up_test(SLS_STR("Char Escape Single quote"), SLS_STR("'\\''")); LexerTest test = start_up_test(SLS_STR("Char Escape Backslash"), SLS_STR("'\\\\'"));
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0; size_t i = 0;
if (test_character_value(&test, result, i++, &(uint8_t){39})) return test.result; if (test_character_value(&test, result, i++, &(uint8_t){92})) return test.result;
if (test_eof_value(&test, result, i++, 0)) return test.result;
return pass_test(&test, result);
}
static TestResult test_Char_Escape_Tab() {
LexerTest test = start_up_test(SLS_STR("Char Escape Tab"), SLS_STR("'\\t'"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_character_value(&test, result, i++, &(uint8_t){9})) return test.result;
if (test_eof_value(&test, result, i++, 0)) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result;
return pass_test(&test, result); return pass_test(&test, result);
} }
@ -2123,16 +2133,6 @@ static TestResult test_Char_Escape_Carriage_return() {
return pass_test(&test, result); return pass_test(&test, result);
} }
static TestResult test_Char_Escape_Newline() {
LexerTest test = start_up_test(SLS_STR("Char Escape Newline"), SLS_STR("'\\n'"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_character_value(&test, result, i++, &(uint8_t){10})) return test.result;
if (test_eof_value(&test, result, i++, 0)) return test.result;
return pass_test(&test, result);
}
static TestResult test_Char_With_Leading_Whitespace() { static TestResult test_Char_With_Leading_Whitespace() {
LexerTest test = start_up_test(SLS_STR("Char With Leading Whitespace"), SLS_STR(" 'A'")); LexerTest test = start_up_test(SLS_STR("Char With Leading Whitespace"), SLS_STR(" 'A'"));
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
@ -3845,10 +3845,10 @@ TestsReport run_lexer_tests() {
test_report.tests[i++] = test_Float_Default_Negative_Zero(); test_report.tests[i++] = test_Float_Default_Negative_Zero();
test_report.tests[i++] = test_Float_f32_Positive_Zero(); test_report.tests[i++] = test_Float_f32_Positive_Zero();
test_report.tests[i++] = test_Float_f32_Negative_Zero(); test_report.tests[i++] = test_Float_f32_Negative_Zero();
test_report.tests[i++] = test_Char_Simple_Letter_A(); test_report.tests[i++] = test_Char_Simple_Letter_Uppercase_A();
test_report.tests[i++] = test_Char_Simple_Letter_a(); test_report.tests[i++] = test_Char_Simple_Letter_Lowercase_a();
test_report.tests[i++] = test_Char_Simple_Letter_Z(); test_report.tests[i++] = test_Char_Simple_Letter_Uppercase_Z();
test_report.tests[i++] = test_Char_Simple_Letter_z(); test_report.tests[i++] = test_Char_Simple_Letter_Lowercase_z();
test_report.tests[i++] = test_Char_Digit_0(); test_report.tests[i++] = test_Char_Digit_0();
test_report.tests[i++] = test_Char_Digit_5(); test_report.tests[i++] = test_Char_Digit_5();
test_report.tests[i++] = test_Char_Digit_9(); test_report.tests[i++] = test_Char_Digit_9();
@ -3872,12 +3872,12 @@ TestsReport run_lexer_tests() {
test_report.tests[i++] = test_Char_Right_Bracket(); test_report.tests[i++] = test_Char_Right_Bracket();
test_report.tests[i++] = test_Char_Left_Brace(); test_report.tests[i++] = test_Char_Left_Brace();
test_report.tests[i++] = test_Char_Right_Brace(); test_report.tests[i++] = test_Char_Right_Brace();
test_report.tests[i++] = test_Char_Escape_Tab();
test_report.tests[i++] = test_Char_Escape_Backslash();
test_report.tests[i++] = test_Char_Escape_Null_character();
test_report.tests[i++] = test_Char_Escape_Single_quote(); test_report.tests[i++] = test_Char_Escape_Single_quote();
test_report.tests[i++] = test_Char_Escape_Carriage_return();
test_report.tests[i++] = test_Char_Escape_Newline(); test_report.tests[i++] = test_Char_Escape_Newline();
test_report.tests[i++] = test_Char_Escape_Null_character();
test_report.tests[i++] = test_Char_Escape_Backslash();
test_report.tests[i++] = test_Char_Escape_Tab();
test_report.tests[i++] = test_Char_Escape_Carriage_return();
test_report.tests[i++] = test_Char_With_Leading_Whitespace(); test_report.tests[i++] = test_Char_With_Leading_Whitespace();
test_report.tests[i++] = test_Char_With_Trailing_Whitespace(); test_report.tests[i++] = test_Char_With_Trailing_Whitespace();
test_report.tests[i++] = test_Char_With_Both_Whitespace(); test_report.tests[i++] = test_Char_With_Both_Whitespace();

View File

@ -5,7 +5,7 @@ build-backend = "sls_build_backend"
[project] [project]
name = "sls_python" name = "sls_python"
version = "0.0.1-alpha" version = "0.0.2-alpha"
description = "Python reimplementation of the SLS C project" description = "Python reimplementation of the SLS C project"
authors = [ { name = "Kyler Olsen" } ] authors = [ { name = "Kyler Olsen" } ]
readme = "README.md" readme = "README.md"

View File

@ -1,6 +1,6 @@
import subprocess import subprocess
from datetime import datetime, timezone from datetime import datetime, timezone
version = "0.0.1-alpha" version = "0.0.2-alpha"
try: try:
__result_hash = subprocess.check_output( __result_hash = subprocess.check_output(
["git", "describe", "--always", "--dirty", "--abbrev=7"], ["git", "describe", "--always", "--dirty", "--abbrev=7"],

View File

@ -6,7 +6,13 @@ Implements classic HP calculator interface with stack display
import tkinter as tk import tkinter as tk
from tkinter import ttk, font as tkfont from tkinter import ttk, font as tkfont
import sls_py from .. import (
InterpreterState,
LexerInfo,
lexical_analysis,
TokenType,
StackType,
)
class SlsCalculator: class SlsCalculator:
def __init__(self, root): def __init__(self, root):
@ -16,8 +22,8 @@ class SlsCalculator:
self.root.resizable(False, False) self.root.resizable(False, False)
# Initialize interpreter # Initialize interpreter
self.interp = sls_py.InterpreterState() self.interp = InterpreterState()
self.lexer = sls_py.LexerInfo() self.lexer = LexerInfo()
# Current entry buffer # Current entry buffer
self.entry_buffer = "" self.entry_buffer = ""
@ -199,10 +205,10 @@ class SlsCalculator:
self.lexer.column = 1 self.lexer.column = 1
self.lexer.line = 1 self.lexer.line = 1
tokens = sls_py.lexical_analysis(self.lexer) tokens = lexical_analysis(self.lexer)
for token in tokens: for token in tokens:
if token.type == sls_py.TokenType.EOF: if token.type == TokenType.EOF:
break break
if not self.interp.execute(token): if not self.interp.execute(token):
print(f"Error executing: {code}") print(f"Error executing: {code}")
@ -235,9 +241,9 @@ class SlsCalculator:
def format_stack_entry(self, entry): def format_stack_entry(self, entry):
"""Format a stack entry for display""" """Format a stack entry for display"""
if entry.type == sls_py.StackType.I64: if entry.type == StackType.I64:
return str(entry.value) return str(entry.value)
elif entry.type == sls_py.StackType.DOUBLE: elif entry.type == StackType.DOUBLE:
val = entry.value val = entry.value
# Format with appropriate precision # Format with appropriate precision
if abs(val) < 1e-10 and val != 0: if abs(val) < 1e-10 and val != 0:
@ -246,7 +252,7 @@ class SlsCalculator:
return f"{val:.6e}" return f"{val:.6e}"
else: else:
return f"{val:.10g}" return f"{val:.10g}"
elif entry.type == sls_py.StackType.BOOLEAN: elif entry.type == StackType.BOOLEAN:
return str(entry.value) return str(entry.value)
else: else:
return str(entry.value) return str(entry.value)

View File

@ -1,5 +0,0 @@
def test_import_package():
import sls
assert hasattr(sls, "__version__")
assert isinstance(sls.__version__, str)

View File

@ -1,6 +1,6 @@
[package] [package]
name = "sls_rs" name = "sls_rs"
version = "0.0.1-alpha" version = "0.0.2-alpha"
edition = "2021" edition = "2021"
[dependencies] [dependencies]

View File

@ -12,7 +12,7 @@ use repl::repl;
// These mirror the C macros. // These mirror the C macros.
const SLS_NAME: &str = "SLS_RUST"; const SLS_NAME: &str = "SLS_RUST";
const SLS_VER: &str = "0.0.1-alpha"; const SLS_VER: &str = "0.0.2-alpha";
pub fn print_version() { pub fn print_version() {
let git_hash = option_env!("GIT_COMMIT_HASH").unwrap_or("unknown"); let git_hash = option_env!("GIT_COMMIT_HASH").unwrap_or("unknown");