From 3b5678815f010bd016ca561e4672d2d83271cb2e Mon Sep 17 00:00:00 2001 From: Dave Gauer Date: Wed, 23 Dec 2020 12:02:35 -0500 Subject: [PATCH] Initial commit with readme, script, and hello world Absolutely minimum viable stuff. --- .gitignore | 2 + 01_hello.zig | 47 ++++++++++++++++++++++++ README.md | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++ ziglings | 63 +++++++++++++++++++++++++++++++ 4 files changed, 214 insertions(+) create mode 100644 .gitignore create mode 100644 01_hello.zig create mode 100644 README.md create mode 100755 ziglings diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b72f9be --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*~ +*.swp diff --git a/01_hello.zig b/01_hello.zig new file mode 100644 index 0000000..a77d919 --- /dev/null +++ b/01_hello.zig @@ -0,0 +1,47 @@ +// Oh no! This program is supposed to print "Hello world!" but it has some +// mistakes. Let's fix it. +// +// We're trying to import the Standard Library into the top level of our +// application. The standard library is not named "foo", it is named "std". +// +// Please correct the name in both places in the import here: +const foo = @import("foo"); + +// Zig applications start by calling a function named 'main'. It needs to be +// public so that it is accessible outside our file! +// +// Public functions are declared with the 'pub' keyword like so: +// +// pub fn my_function() void { ... } +// +// Please make the main() function public: +fn main() void { + + // The easiest way to display our "Hello world" message in the + // terminal is to use the std.debug.print() function. + + // Please fix this silly "foo" mistake here: + foo.debug.print("Hello world!\n", .{}); + + // The print function above takes two values: + // + // 1. A string of characters: "Hello world!\n". "\n" prints a new line. + // + // 2. A struct containing data to be displayed. .{} is an empty, nameless + // struct fulfilling the requirement. More about structs later. + // + // + // Now we're ready to...What's this!? Oh, we wanted to print a Goodbye + // message as well! + // + // Please fix this to use the same print function as above: + "Goodbye!\n" +} + +// Once you're done with the changes above, run `ziglings` to see if it passes. +// +// Finally, all files will contain the following comment: +// +// I AM NOT DONE +// +// Delete it when you're ready to continue to the next exercise! diff --git a/README.md b/README.md new file mode 100644 index 0000000..2e49f83 --- /dev/null +++ b/README.md @@ -0,0 +1,102 @@ +# ziglings + +Welcome to `ziglings`. This project contains a series of incomplete exercises. +By completing the exercises, you learn how to read and write +[Zig](https://ziglang.org/) +code. + +This project was directly inspired by the brilliant and fun +[rustlings](https://github.com/rust-lang/rustlings) +project for the [Rust](https://www.rust-lang.org/) language. + +## Getting Started + +_Note: This currently uses a shell (Bash) script to automate the "game". A +future update may remove this requirement. See TODO below._ + +Install the [master release](https://ziglang.org/download/) of the Zig compiler. + +Verify the installation and version of `zig` like so: + +```bash +$ zig version +0.7.1+ +``` + +Clone this repository with Git: + +```bash +git clone https://github.com/ratfactor/ziglings +cd ziglings +``` + +Then run the `ziglings` script and follow the instructions to begin! + +```bash +./ziglings +``` + +## Manual Usage + +If you can't (or don't want to) use the script, you can manually verify each +exercise with the Zig compiler. + +Some exercises need to be "run" (compiled and executed): + +```bash +zig run exercises/01_hello.zig +``` + +Some exercises need to be tested: + +```bash +zig test exercises/02_hello_test.zig +``` + +## TODO + +Contributions are very welcome! I'm writing this to teach myself and to create +the learning resource I wished for. There will be tons of room for improvement: + +* Wording of explanations +* Idiomatic usage of Zig +* Additional exercises +* Re-write the `ziglings` script using the Zig build system (???) + +Planned exercises: + +* [x] Hello world +* [ ] Hello tests +* [ ] Assignment +* [ ] Arrays +* [ ] If +* [ ] While +* [ ] For +* [ ] Functions +* [ ] Defer +* [ ] Errors +* [ ] Switch +* [ ] Runtime safety +* [ ] Unreachable +* [ ] Pointers +* [ ] Pointer sized integers +* [ ] Multi pointers +* [ ] Slices +* [ ] Enums +* [ ] Structs +* [ ] Unions +* [ ] Integer rules +* [ ] Floats +* [ ] Labelled blocks +* [ ] Labelled loops +* [ ] Loops as expressions +* [ ] Optionals +* [ ] Comptime +* [ ] Inline loops +* [ ] Anonymous structs +* [ ] Sentinel termination +* [ ] Vectors +* [ ] Imports + +The initial topics for these exercises were unabashedly cribbed from +[ziglearn.org](https://ziglearn.org/). diff --git a/ziglings b/ziglings new file mode 100755 index 0000000..3c91fee --- /dev/null +++ b/ziglings @@ -0,0 +1,63 @@ +#!/bin/bash + +# Minimum viable working example! + +echo +echo " _ _ _ " +echo " ___(_) __ _| (_)_ __ __ _ ___ " +echo " |_ | |/ _' | | | '_ \ / _' / __| " +echo " / /| | (_| | | | | | | (_| \__ \ " +echo " /___|_|\__, |_|_|_| |_|\__, |___/ " +echo " |___/ |___/ " +echo + +# Capture terminal escape sequences (ANSI) for formatting +fmt_err=$( tput setaf 1 ) # red foreground +fmt_yay=$( tput setaf 2 ) # green foreground +fmt_off=$( tput sgr0 ) # reset colors/effects + + + +# TODO: most of this belongs in a generalized function +if grep -q "I AM NOT DONE" 01_hello.zig +then + +echo +echo "* Exercise: Hello world *" + +result=$(zig run 01_hello.zig 2>&1) +result_status=$? +echo ========================================================================= +echo "$result" +echo ========================================================================= +if [[ $result_status -eq 0 ]] +then + printf "${fmt_yay}Zig was able to compile your submission.${fmt_off}\n" +else + printf "${fmt_err}Uh oh! Looks like there was an error.${fmt_off}\n" + exit +fi + +if [[ $result == *Hello*Goodbye* ]] +then + printf "${fmt_yay}Excellent! I see that you're printing both Hello and Goodbye!${fmt_off}\n" +else + printf "${fmt_err}It seems to compile, but...${fmt_off}\n" + exit +fi + +echo "Now you're ready to move on!" +echo "Delete the line I AM NOT DONE from the source file when you're ready" +echo "to continue." + +exit + +else # end of exercise one - I AM NOT DONE is removed! + printf "${fmt_yay}DONE - Hello world${fmt_off}\n" +fi + + +echo +echo "* Exercise: Hello test *" +echo +echo "TODO: this and other exercises :-)"