Nimbin[12]?SDL & Graphics / sdl_runtime_compiler / src/levels/level/char_copy.cpp

sdl_runtime_compiler git · main

SDL3 game for running and compiling code at runtime

sdl3 c++ compiler dlopen cmake · first commit 2026-04-19 · last commit 2026-07-03 (3 months ago) · synced 3 days ago · upstream: git.ide3.de/hsnr/sdl-runtime-compiler

C++ 72.3% C 26.2%
git clone https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler.gitwget https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler/archive/sdl_runtime_compiler.tar.gz
src/levels/level/char_copy.cpp 8.2 KB · 190 lines raw
#include "levels/level.hpp"
#include "utils/config.hpp"

namespace
Nimbin
{

Level::Data
Level::build_CharCopy()
{
    return {
        .steps = {
            // ── Step 0: main scaffold ─────────────────────────────────────
            {
                .grants = {
                    Level::TokenGrant::give("int"),
                    Level::TokenGrant::give("main"),
                    Level::TokenGrant::give("("),
                    Level::TokenGrant::choice({ "void", "int", "char" }),
                    Level::TokenGrant::give(")"),
                    Level::TokenGrant::give("{"),
                    Level::TokenGrant::give("return"),
                    Level::TokenGrant::give("0"),
                    Level::TokenGrant::give(";"),
                    Level::TokenGrant::give("}"),
                },
                .scene        = {},
                .goal         = Goal::CompilePattern{ "int main ( void ) { return 0 ; }" },
                .hint    = "Build a working main()",
                .details = R"(C programs start at main().

main() returns an int and takes 'void' to declare no arguments.
The body returns 0 to mean success.

Goal:
  int main(void) {
      return 0;
  }

Grab tokens and arrange them on the editor wall.)",
                .reset_carry  = false,
                .max_ai_words = 3,
            },
            // ── Step 1: copy_str signature ────────────────────────────────
            {
                .grants = {
                    Level::TokenGrant::give("void"),
                    Level::TokenGrant::give("copy_str"),
                    Level::TokenGrant::give("("),
                    Level::TokenGrant::choice({ "char", "int", "float" }),
                    Level::TokenGrant::give("src"),
                    Level::TokenGrant::give("["),
                    Level::TokenGrant::give("]"),
                    Level::TokenGrant::give(","),
                    Level::TokenGrant::give("char"),
                    Level::TokenGrant::give("dst"),
                    Level::TokenGrant::give("["),
                    Level::TokenGrant::give("]"),
                    Level::TokenGrant::give(")"),
                    Level::TokenGrant::give("{"),
                    Level::TokenGrant::give("}"),
                },
                .scene        = {},
                .goal         = Goal::CompilePattern{ "void copy_str ( char src [ ] , char dst [ ] ) { }" },
                .hint    = "Declare the copy_str function",
                .details = R"(Now add a function above main().

copy_str takes two char arrays — a source and a destination —
and returns nothing (void).

Note the brackets [ ] on each parameter — that marks them
as arrays.

Goal:
  void copy_str(char src[], char dst[]) {
  }
  int main(void) { ... }

Place this BEFORE main.)",
                .reset_carry  = false,
                .max_ai_words = 3,
            },
            // ── Step 2: loop counter ──────────────────────────────────────
            {
                .grants = {
                    Level::TokenGrant::choice({ "int", "float", "char" }),
                    Level::TokenGrant::give("i"),
                    Level::TokenGrant::give(";"),
                },
                .scene        = {},
                .goal         = Goal::CompilePattern{ "void copy_str ( char src [ ] , char dst [ ] ) { int i ; }" },
                .hint    = "Add a loop counter inside copy_str",
                .details = R"(Inside copy_str's body, declare an integer
to track our position in the array.

Goal (inside copy_str):
  int i;

You only need to add ONE line. Place it between the { and }
of copy_str.)",
                .reset_carry  = false,
                .max_ai_words = 3,
            },
            // ── Step 3: for loop scaffold ─────────────────────────────────
            {
                .grants = {
                    Level::TokenGrant::give("for"), Level::TokenGrant::give("("),
                    Level::TokenGrant::give("i"), Level::TokenGrant::give("="), Level::TokenGrant::give("0"), Level::TokenGrant::give(";"),
                    Level::TokenGrant::give("i"), Level::TokenGrant::give("<"), Level::TokenGrant::give("strlen"),
                    Level::TokenGrant::give("("), Level::TokenGrant::give("src"), Level::TokenGrant::give(")"), Level::TokenGrant::give(";"),
                    Level::TokenGrant::give("i"), Level::TokenGrant::give("++"), Level::TokenGrant::give(")"),
                    Level::TokenGrant::give("{"), Level::TokenGrant::give("}"),
                },
                .scene        = {},
                .goal         = Goal::CompilePattern{ "for ( i = 0 ; i < strlen ( src ) ; i ++ ) { }" },
                .hint    = "Loop through src",
                .details = R"(Add a for loop after 'int i;'.

It starts at 0 and stops when i reaches the length of src.
strlen() gives the length of a C string.

Goal:
  for (i = 0; i < strlen(src); i++) {
  }

This is the loop scaffold only — the body comes next.)",
                .reset_carry  = false,
                .max_ai_words = 3,
            },
            // ── Step 4: copy the character ────────────────────────────────
            {
                .grants = {
                    Level::TokenGrant::give("dst"), Level::TokenGrant::give("["), Level::TokenGrant::give("i"), Level::TokenGrant::give("]"),
                    Level::TokenGrant::give("="),
                    Level::TokenGrant::give("src"), Level::TokenGrant::give("["), Level::TokenGrant::give("i"), Level::TokenGrant::give("]"),
                    Level::TokenGrant::give(";"),
                },
                .scene        = {},
                .goal         = Goal::CompilePattern{ "dst [ i ] = src [ i ] ;" },
                .hint    = "Copy one character per iteration",
                .details = R"(Inside the for loop body, copy src[i] into dst[i].

This single statement is the heart of the function — it
copies the i-th character on each pass through the loop.

Goal (inside the for loop):
  dst[i] = src[i];)",
                .reset_carry  = false,
                .max_ai_words = 3,
            },
            // ── Step 5: call copy_str and print ──────────────────────────
            {
                .grants = {
                    Level::TokenGrant::give("char"), Level::TokenGrant::give("dst"), Level::TokenGrant::give("["),
                    Level::TokenGrant::give("100"),  Level::TokenGrant::give("]"),   Level::TokenGrant::give(";"),

                    Level::TokenGrant::give("copy_str"), Level::TokenGrant::give("("),
                    Level::TokenGrant::give("\"hello\""),
                    Level::TokenGrant::give(","), Level::TokenGrant::give("dst"),
                    Level::TokenGrant::give(")"), Level::TokenGrant::give(";"),

                    Level::TokenGrant::give("printf"), Level::TokenGrant::give("("),
                    Level::TokenGrant::choice({ "\"%s\"", "\"%d\"", "\"%c\"" }),
                    Level::TokenGrant::give(","), Level::TokenGrant::give("dst"),
                    Level::TokenGrant::give(")"), Level::TokenGrant::give(";"),
                },
                .scene        = {},
                .goal         = Goal::CompilePattern{ "char dst [ 100 ] ; copy_str ( \"hello\" , dst ) ; printf ( \"%s\" , dst ) ;" },
                .hint    = "Call copy_str and print the result",
                .details = R"(In main(), do three things before 'return 0;':

1. Declare a buffer:    char dst[100];
2. Call copy_str:       copy_str("hello", dst);
3. Print the result:    printf("%s", dst);

The buffer holds the copied characters.
copy_str fills it. printf displays it.

Place all three lines BEFORE the existing return.)",
                .reset_carry  = false,
                .max_ai_words = 3,
            },
        },
        .name = "Char Copy",
        .desc = "Implement a function that copies a char array and prints the result.",
        .dynamic_lib = false,
    };
}

} // namespace Nimbin