From ea9e361b8fe4c93e1703ffa715d60afd21d3a934 Mon Sep 17 00:00:00 2001 From: StackClass Date: Mon, 25 Aug 2025 04:50:38 +0000 Subject: [PATCH] Initial commit from template --- .gitattributes | 1 + .gitignore | 10 ++++++ .stackclass/compile.sh | 11 ++++++ .stackclass/run.sh | 11 ++++++ Cargo.lock | 79 ++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 10 ++++++ Dockerfile | 20 +++++++++++ README.md | 46 ++++++++++++++++++++++++ src/main.rs | 35 +++++++++++++++++++ stackclass.yml | 18 ++++++++++ your_program.sh | 24 +++++++++++++ 11 files changed, 265 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100755 .stackclass/compile.sh create mode 100755 .stackclass/run.sh create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 src/main.rs create mode 100644 stackclass.yml create mode 100755 your_program.sh diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..176a458 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..73fab07 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb diff --git a/.stackclass/compile.sh b/.stackclass/compile.sh new file mode 100755 index 0000000..d2b4072 --- /dev/null +++ b/.stackclass/compile.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script is used to compile your program on StackClass +# +# This runs before .stackclass/run.sh +# +# Learn more: https://docs.stackclass.dev/challenges/program-interface + +set -e # Exit on failure + +cargo build --release diff --git a/.stackclass/run.sh b/.stackclass/run.sh new file mode 100755 index 0000000..a916ca6 --- /dev/null +++ b/.stackclass/run.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script is used to run your program on StackClass +# +# This runs after .stackclass/compile.sh +# +# Learn more: https://docs.stackclass.dev/challenges/program-interface + +set -e # Exit on failure + +exec target/release/stackclass-interpreter "$@" diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..24f775d --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,79 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "stackclass-interpreter" +version = "0.1.0" +dependencies = [ + "anyhow", + "bytes", + "thiserror", +] + +[[package]] +name = "syn" +version = "2.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6397daf94fa90f058bd0fd88429dd9e5738999cca8d701813c80723add80462" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..80be101 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "stackclass-interpreter" +version = "0.1.0" +authors = ["StackClass "] +edition = "2021" + +[dependencies] +anyhow = "1.0.98" # error handling +bytes = "1.10.1" # helps manage buffers +thiserror = "2.0.12" # error handling diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0cdea76 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +# syntax=docker/dockerfile:1.7-labs +FROM rust:1.87-slim-bookworm AS builder + +WORKDIR /app + +# .git & README.md are unique per-repository. We ignore them on first copy to prevent cache misses +COPY --exclude=.git --exclude=README.md . /app + +# This runs cargo build +RUN .stackclass/compile.sh + +# Final minimal image +FROM debian:bookworm-slim + +WORKDIR /app +COPY --from=builder --exclude=target /app ./ +COPY --from=builder /app/target/release/stackclass-interpreter ./target/release/ + +# Set default startup command +CMD ["./.stackclass/run.sh"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..ae677ba --- /dev/null +++ b/README.md @@ -0,0 +1,46 @@ +This is a starting point for Rust solutions to the +"Build your own Interpreter" Challenge. + +This challenge follows the book +[Crafting Interpreters](https://craftinginterpreters.com/) by Robert Nystrom. + +In this challenge you'll build an interpreter for +[Lox](https://craftinginterpreters.com/the-lox-language.html), a simple +scripting language. Along the way, you'll learn about tokenization, ASTs, +tree-walk interpreters and more. + +Before starting this challenge, make sure you've read the "Welcome" part of the +book that contains these chapters: + +- [Introduction](https://craftinginterpreters.com/introduction.html) (chapter 1) +- [A Map of the Territory](https://craftinginterpreters.com/a-map-of-the-territory.html) + (chapter 2) +- [The Lox Language](https://craftinginterpreters.com/the-lox-language.html) + (chapter 3) + +These chapters don't involve writing code, so they won't be covered in this +challenge. This challenge will start from chapter 4, +[Scanning](https://craftinginterpreters.com/scanning.html). + +# Passing the first stage + +The entry point for your program is in `src/main.rs`. Study and uncomment the +relevant code, and push your changes to pass the first stage: + +```sh +git commit -am "pass 1st stage" # any msg +git push origin main +``` + +Time to move on to the next stage! + +# Stage 2 & beyond + +Note: This section is for stages 2 and beyond. + +1. Ensure you have `cargo (1.87)` installed locally +2. Run `./your_program.sh` to run your program, which is implemented in + `src/main.rs`. This command compiles your Rust project, so it might be slow + the first time you run it. Subsequent runs will be fast. +3. Commit your changes and run `git push origin main` to submit your solution + to StackClass. Test output will be streamed to your terminal. diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..c26e692 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,35 @@ +use std::env; +use std::fs; + +fn main() { + let args: Vec = env::args().collect(); + if args.len() < 3 { + eprintln!("Usage: {} tokenize ", args[0]); + return; + } + + let command = &args[1]; + let filename = &args[2]; + + match command.as_str() { + "tokenize" => { + // You can use print statements as follows for debugging, they'll be visible when running tests. + eprintln!("Logs from your program will appear here!"); + + let file_contents = fs::read_to_string(filename).unwrap_or_else(|_| { + eprintln!("Failed to read file {filename}"); + String::new() + }); + + // Uncomment this block to pass the first stage + // if !file_contents.is_empty() { + // panic!("Scanner not implemented"); + // } else { + // println!("EOF null"); // Placeholder, replace this line when implementing the scanner + // } + } + _ => { + eprintln!("Unknown command: {command}"); + } + } +} diff --git a/stackclass.yml b/stackclass.yml new file mode 100644 index 0000000..a61542a --- /dev/null +++ b/stackclass.yml @@ -0,0 +1,18 @@ +# Set this to true if you want debug logs. +# +# These can be VERY verbose, so we suggest turning them off +# unless you really need them. +debug: false + +# Use this to change the Rust version used to run your code +# on StackClass. +# +# Available versions: rust-1.87 +language_pack: rust-1.87 + +# The executable required to build and run the this project, +# along with its minimum required version. +required_executable: cargo (1.87) + +# The main source file that users can edit for this project. +user_editable_file: src/main.rs diff --git a/your_program.sh b/your_program.sh new file mode 100755 index 0000000..de170c2 --- /dev/null +++ b/your_program.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# +# Use this script to run your program LOCALLY. +# +# Note: Changing this script WILL NOT affect how StackClass runs your program. +# +# Learn more: https://docs.stackclass.dev/challenges/program-interface + +set -e # Exit early if any commands fail + +# Copied from .stackclass/compile.sh +# +# - Edit this to change how your program compiles locally +# - Edit .stackclass/compile.sh to change how your program compiles remotely +( + cd "$(dirname "$0")" # Ensure compile steps are run within the repository directory + cargo build --release +) + +# Copied from .stackclass/run.sh +# +# - Edit this to change how your program runs locally +# - Edit .stackclass/run.sh to change how your program runs remotely +exec target/release/stackclass-interpreter "$@"