|
A Guide for an AI when Vibe Coding |
This guide is written for AI language models generating Sheerpower code. It focuses on the patterns most likely to produce incorrect output when models apply habits from C, Python, JavaScript, or Java — and shows the correct Sheerpower form alongside each trap.
Generate only syntax that appears in this guide or in the official Sheerpower tutorials. When a statement, function name, parameter, or syntax rule cannot be confirmed from either source, do not invent a plausible-looking substitute. Instead, choose one of the following actions:
I am not certain whether Sheerpower's string-search
function is pos(), index(), or find(). Please confirm before I
continue.
Before writing the file I/O section, I need to re-read
the File I/O tutorial. Is it available?
// UNVERIFIED: exact syntax for sorting a cluster array descending // confirm against Cluster Sorting tutorial before running
A compile error on a marked gap is recoverable. A confabulated routine name buried in otherwise correct-looking code is not — it fails silently, erodes trust, and can take longer to track down than the original task.
Takeaway: Stop, mark, or ask — in that order. If a piece of Sheerpower syntax cannot be traced to this guide or the tutorials, that is the signal to pause, not proceed.
This document is structured around error patterns observed in generated code — not around language features.
The goal is simple: eliminate predictable errors in generated code before they reach execution.
Human readers will also find this a useful quick-reference for the rules that differ most from mainstream languages.
//, but ! is okay for all new code.call prefix keyword, use named parameters.with arguments are read-only within the routine — compiler enforced.select case — always include case else.retry vs. continue.do / repeat do / end do.$, ?, and bare names.sprintf$() format specifiers.collect cluster before for each.findrow() for fast single-row lookup.VIEW statement.element$(), elements(), size(), str$(), and pass._GID$ special variable.To maximize portability, compatibility, and long-term maintainability, use only ASCII characters in all Sheerpower source code.
Sheerpower is case-insensitive. For consistency, write all code in lower-case and use snake_case for multi-word identifiers. Where ever possible, use meaningful variable names. This helps both code validation and code maintenance later on.
This is the single most common error in AI-generated Sheerpower code.
Sheerpower has no call prefix keyword when invoking routines.
Routines are invoked by just their name, followed by with
for inputs and returning for outputs. Sheerpower routine
names cannot contain $ or ? characters.
All with arguments are read-only within the routine —
compiler enforced.
call routine_name(args) or result = routine_name(args).call keyword and no parentheses on routine invocations.call. Never write
result = routine_name(args). Use the
with / returning syntax below.
All three forms are equivalent. The implied form works when your local variable names exactly match the routine's parameter names.
Parameters are read-only inside the routine by default. Do not
attempt to assign to a with parameter — it is not
allowed by the compiler.
Sheerpower does not support user-defined functions. Instead, use routines with returning parameter values.
This approach improves clarity, especially when multiple values need to be returned, and keeps all logic within a consistent routine-based structure.
Every block in Sheerpower has an explicit named terminator. Missing or mismatching a terminator is a common AI error, especially when generating nested structures.
end ___ keyword — no braces.
There are no braces. There is no endif as a single word —
it must be written end if with a space.
for loops — both numeric and for each —
close with next varname, not an end keyword.
select case Requires case else
When generating a select case block, always include
case else. If no case matches and there is no
case else, the program can fail at runtime.
select case blocks with only the expected cases. This is
fragile because real data can contain unexpected values.case else as
the fallback branch.select case
block should include case else.
VAL() as the Primary Way to Parse Numbers
From Text
In Sheerpower, the primary way to extract numbers from text is
VAL(). When numeric data appears inside a larger string,
do not assume the text must be split apart first, and do not invent
manual parsing helpers unless they are truly necessary.
Use VAL(string$) when the entire string should be a
number. Use VAL(string$, Nth) when the string may contain
embedded numbers and you want the first, second, third, or later
numeric value. This makes VAL() the standard tool for
parsing values from user input, reports, logs, messages, and mixed
text.
For example, given the string
"I need 5 widgets at $12.99 each", you can extract the
numbers directly:
This extracts 5 and 12.99 without any manual
parsing or string splitting.
If parsing may fail, check _integer immediately after the
call. A value of 0 means no valid number was found. When needed, use
the optional parsing options to handle separators, ignored characters,
negative formats such as parentheses, or European number conventions.
In short: when an AI needs to get a number out of text in Sheerpower,
it should think of VAL() first.
Sheerpower has two forms of exception handler. The words
retry and continue mean something specific
here and must not be confused with loop control.
retry and
continue, or use throw / raise
/ except from other languages.cause exception.retry = re-run the failing statement after fixing the cause.
continue = skip the failing statement and move on.
Never write throw, raise, except,
or catch.
Sheerpower's main loop construct is do / end do.
The keyword that restarts the loop from the top is
repeat do — not continue.
The keyword that exits is exit do.
continue inside
a loop intending to restart the iteration. In Sheerpower,
continue is an exception-handler keyword only.repeat do to restart a
do loop. Use exit do to break out.repeat do is explicit about
intent — there is no ambiguity about which loop is being restarted
in nested structures.continue.
Write repeat do to cycle, exit do to leave.
continue inside
for loops to skip to the next iteration or break
to exit. Neither keyword exists for loop control in Sheerpower.iterate for skips to the next
for iteration. repeat do restarts a
do loop. Never use continue or
break for loop control.
There is no return statement in Sheerpower.
To exit a routine before reaching its end, use exit routine.
Sheerpower uses visual suffixes to declare variable type implicitly. These are part of the variable name, not operators.
? suffix
on boolean variables, generating is_active = true
instead of is_active? = true.? when declared implicitly. Without the
suffix, Sheerpower creates a REAL variable and true
stores as 1.var, let, int, or
float declarations needed for most cases.? suffix. Check every string variable name for
the $ suffix.
Sheerpower string literals are treated as raw text. There are no escape sequences inside strings.
\n, \t, or
\\, or double-escape backslashes unnecessarily.Do not apply escape rules from other languages. Write exactly the characters you want stored in the string.
Sheerpower has its own date and time functions, and these should be used for all date and time manipulation.
Do not assume date or time syntax from other programming languages.
Before writing any date or time code, note these specific patterns that AIs frequently get wrong in Sheerpower:
SECONDS() requires a full datetime string, not
just a date. A variable containing only
YYYY-MM-DD will cause an
illegal time format error.
format_duration(). Use the built-in date and time
functions instead.
To avoid common AI confabulations, read this tutorial carefully before writing or explaining any Sheerpower code that works with dates or times:
Date and Time Functions Tutorial
Problem: In most mainstream languages (Python, Java,
JavaScript, C++), numeric calculations use IEEE 754 binary
floating-point. These values cannot exactly represent many
decimal numbers. This leads to small but visible errors in
results (for example,
0.1 + 0.2 = 0.30000000000000004).
Because of this, AI-generated code often adds
round(), floor(), or similar
adjustments after calculations to "correct" the result.
Sheerpower Difference: Sheerpower uses Exact REAL values stored in a decimal-accurate format. Decimal values are represented exactly, so calculations produce correct results without adjustment.
Instruction for AI:
Do not add rounding to compensate for floating-point error.
In Sheerpower, the result of a calculation is already
correct. For example, 0.1 + 0.2 evaluates
exactly to 0.3.
Business Logic Only:
Apply rounding only when it is explicitly required by the
business rules, for example, "round tax to the nearest cent."
Do not round as a defensive habit.
Trust the VM:
Sheerpower's Virtual Machine is designed for precise decimal
arithmetic. You can rely on the direct result of any numeric
expression.
Takeaway:
If you are about to write round(total, 2) just to
ensure cents are correct, stop. In Sheerpower, the cents are
already correct.
Clusters are Sheerpower's primary structured data type.
The field-access operator is ->.
for order in orders and then access fields as
order->amount. There is no such iteration variable
in Sheerpower.for each loop,
use the cluster name itself with -> to access fields:
orders->amount.for each iterates the
collected result set directly with no temporary object allocation.collect Before for each
Before iterating a cluster array with for each, collect
the cluster. This step prepares the current result set for iteration.
Without a collect cluster, a for each loop may
not iterate the rows you expect.
for each loops without first collecting the cluster.collect cluster before
every for each iteration, even when no filtering or
sorting is needed.collect defines the active
result set. It can also apply filtering, sorting, and selection before
iteration begins.collect is the
required setup step before for each.
findrow() for Single-Row Lookup
When looking up a single row in a cluster, use
findrow(). Do not generate a full
collect / include / for each / exit for loop just to find
one matching row.
findrow() for direct
lookup when the goal is to find one matching row.findrow() is the idiomatic
Sheerpower way to perform fast single-row lookup, rather than scanning
rows manually.findrow() before writing a loop.
VIEW creates a zero-copy window into a source string.
It does not allocate a new string — it references a position
and length within the original buffer. The clauses must appear
in the correct order.
VIEW
entirely and generate slow substring loops, or get the clause
ordering wrong.INTO names the source. The remaining clauses
such as MID, PIECE, MATCH, and related options describe how to
locate the window.VIEW before reaching for mid$() or
string concatenation.
The following keywords are common in other languages. None of them exist in Sheerpower. Generating them will produce a compile error.
Output uses print. Items are separated by semicolons.
A trailing semicolon suppresses the newline. Tab alignment uses
tab(n).
sprintf$() Format Specifiers
Sheerpower uses sprintf$() for formatted string output.
Do not assume that Sheerpower format strings are the same as C
printf, JavaScript template strings, or Python format
strings.
Several Sheerpower format specifiers are especially important because they appear often in real programs and have no direct equivalent in mainstream languages.
sprintf$() as if it were C printf or
Python formatting. This leads to wrong assumptions about
substitution, pluralization, money formatting, and number-to-words
output.sprintf$() already has
the needed format specifier.
The %p format is used for automatic pluralization. It
takes the count and the singular word:
The bare % format is a general substitution marker. It is
not limited to one data type.
The %m format is commonly used for comma-separated numeric
output, especially money-style output.
The %w format outputs the written-in-words version of a
number, useful for check-writing and business documents.
Use line input when the input may contain spaces or commas.
Use input for simple values.
Several small built-in routines and statements are common in real Sheerpower programs. AI models often invent mainstream-language substitutes for them.
Use element$() and elements() for common
delimited string work. Do not invent split().
Use size() to get the number of rows in a cluster.
Use str$() to convert a number to a string. In
Sheerpower, str$() does not add leading spaces.
Use pass to run an operating system command.
Sheerpower has four routine scopes. Generating the wrong scope
is a common AI error, especially confusing local
and private.
Sheerpower has no user-defined functions that return values. Instead, it has routines, each of which can return up to 16 values. Sheerpower has many dozens of built-in functions.
private when
they mean local, or generate a with clause
on a local routine that shares the parent's scope.local routine sees all
of the parent routine's variables directly. It does not need
parameters for data the parent already has. A private
routine is isolated and must receive data through parameters.local.
If it is a standalone reusable unit, use private or
routine.
Whenever you need a unique ID, use the _GID$ special variable.
It returns a 30-character, browser-safe identifier that combines a date stamp
and a unique ID. The result is both globally unique and sortable by creation date.
Because _gid$ includes a universally unique identifier, two
instances of the same handler running simultaneously will never produce the
same value, even when running on different systems. This eliminates the need
for counters, sequence generators, or inter-process coordination.
Only wrap code in a when exception in block when you intend to
handle the error differently than Sheerpower would on its own. Sheerpower
already stops on unhandled exceptions and automatically reports the error type,
description, call stack, and source location.
A handler earns its place only when it does something Sheerpower's automatic crash report cannot — such as retrying with a fallback, logging before continuing, or allowing the program to recover and keep running.
cluster input name '@fruits.csv', headers 1: fruits
Handler earns its place:
when exception in
cluster input name '@fruits.csv', headers 1: fruits
use
if extype = exceptiontype('filenotfound') then
cluster input name '@fruits_default.csv', headers 1: fruits
else
stop
end if
end when
Takeaway: A use block that only prints
extext$ and stops gives the user less information than
Sheerpower's automatic crash report. Delete it and let Sheerpower handle it.
Order routines so that every routine appears before the routines it calls. The main logic area comes first, then the high-level routines it calls, then the lower-level routines those call, and so on down to leaf routines at the bottom.
Think of it as a newspaper article — headline first, detail later. A reader should be able to start at the top and follow the logic downward without ever needing to jump back up.
Sheerpower web applications commonly use a CGI-style handler pattern. This is not like Flask, Express, PHP, or browser-side JavaScript. Do not invent a web framework pattern from another language.
The common Sheerpower pattern is:
open file cgi://.line input #cgi_ch.getsymbol$() to read submitted values.[[%spscript]] templates for generated output.cgi://, line input,
getsymbol$(), and [[%spscript]] pattern.
Before generating a full Sheerpower web app, re-read the relevant web tutorial or a working web application. This pattern is a major Sheerpower idiom and should not be guessed from other languages.
To write correct and efficient Sheerpower programs, it is important to understand how the compiler processes source code. The lifecycle is simple, deterministic, and designed for both speed and reliability.
Problem:
Many developers assume a traditional multi-phase compiler with separate
analysis, optimization, and linking stages. This leads to incorrect
mental models, especially when reasoning about forward references,
performance, and error behavior.
Solution:
Sheerpower uses a streamlined compilation model with four key stages:
directive processing, incremental super-p-code generation, back-patching, and
virtual machine execution.
Efficiency:
Because code is emitted as it is parsed, compilation is extremely fast.
The final back-patching step resolves forward references without
requiring multiple full passes or complex linking stages.
Takeaway:
Think of Sheerpower as a single-pass compiler with a lightweight
fix-up phase. This mental model explains both its speed and its
predictable behavior.
1. Directive Processing
Before compilation begins, directives such as %include,
%debug, and related settings are processed. This stage
determines which source files are merged and which compile-time
behaviors are enabled.
The result is a fully assembled source stream that the compiler will process as a single, continuous program.
2. Incremental Super-P-Code Generation
As the compiler parses each statement, it immediately generates intermediate instructions, called super-p-code. There is no delayed code generation phase and no separate intermediate representation tree.
Problem:
Traditional virtual machines execute many small, low-level instructions,
which increases interpretation overhead and reduces performance.
Solution:
Sheerpower uses super-p-code, where each instruction represents a
higher-level operation, for example a full expression evaluation or
data movement, rather than a single primitive step.
Efficiency:
By combining multiple low-level operations into a single instruction,
the VM executes fewer steps, reducing dispatch overhead and improving
runtime speed.
Takeaway:
Super-p-code is a "super-instruction" model: fewer, richer instructions
that execute more work per step, making the VM both fast and predictable.
This direct emission model is a key reason Sheerpower can compile very large codebases in extremely short timeframes.
3. Back-Patching
After the initial pass, the compiler performs a fix-up phase known as back-patching. During this step, unresolved addresses are filled in for:
This allows developers to write code in a natural top-down style without needing to predeclare or reorder definitions.
4. VM Execution
The finalized super-p-code is executed by the Sheerpower Virtual Machine. The VM uses highly optimized super-instructions to deliver consistent and predictable performance across platforms.
Because execution is handled by the VM, behavior remains stable and portable, independent of the underlying operating system.
Before submitting generated Sheerpower code, run through this checklist mentally:
call keyword anywhere?with and returning?end ___ terminator?next varname — not end for???$?repeat do for do loops or iterate for for for loops — not continue?exit do or exit for — not break?exit routine — not return?retry or continue — not return?for each loops access fields as clustername->field$?collect cluster appears before every for each?select case includes case else?throw, raise, catch, new, return, break, or end for?VIEW clauses use target INTO source, PIECE delimiter, MATCH index?VAL() first when parsing numbers from text?element$() or elements() for delimited strings — not split()?findrow() for single-row lookup instead of scanning a whole cluster?size() for cluster row counts?str$() for number-to-string conversion?pass for operating system commands?sprintf$() formats such as %, %p, %m, and %w?cgi://, line input, getsymbol$(), and [[%spscript]] pattern?"\n" is two characters: "\" and "n".Vibe coding works best when the feedback loop is short. In Sheerpower, there is no reason to make a large batch of changes before checking the result. The compiler is fast enough that every meaningful code change should be followed immediately by validation.
Problem:
AI-generated code can contain small mistakes: a misspelled variable, a
missing terminator, an incomplete statement, or a routine name that does
not match the source. If many changes are made before compiling, these
small mistakes become harder to isolate.
Solution:
Use a tight cycle: make one change, compile, read the result, fix the
first error, and compile again. Do not guess blindly. Always read the
compiler message and the source line it points to.
Efficiency:
Sheerpower compiles very quickly, so frequent validation is not a burden.
It is the normal workflow. One edit followed by one compile keeps the
AI, the programmer, and the source code aligned.
Takeaway:
For Sheerpower vibe coding, the rule is simple: one edit, one compile,
one test. Keep the loop tight.
After each code change, compile and validate immediately:
Always use PowerShell for this workflow, not bash. Bash can alter or
mangle the line-delimited compiler output. The sp4gl
command is expected to be on the system path, so a full path is not
needed.
Use a build-output filename that matches the program name. For example, if the source file is:
then the build output should be:
This keeps build results easy to find and avoids overwriting results from other programs.
After compiling, check the exit code. If the build failed, read the build output:
The build exit codes are:
0 — clean build1 — compile errorA clean build looks like this:
Compiler error lines follow this format:
The fields are:
When a compile fails, follow this process:
If there are multiple errors, focus on the first one. Later errors are often caused by the first error.
Do not guess at fixes blindly. The error message plus the surrounding source code is usually enough to show what went wrong.
For AI-assisted coding, never invent a fix based only on the error message. First inspect the source line, nearby lines, and the related variable or routine names. Then make the smallest correction that directly explains the compiler error.
| Error message | Typical cause |
|---|---|
| Unknown variable | Typo in a variable name |
| Unexpected end of statement | Missing closing quote, parenthesis, or keyword |
| Expected end if | Mismatched block structure, such as an if without end if |
| Unknown routine | Typo in a routine name, or routine defined after stop |
The following example shows the complete cycle: write, compile, fail, read the error, fix the source, recompile, run, and verify.
Step 1 — write the program:
Step 2 — compile the program:
The exit code is 1. The build output contains:
Step 3 — read the source at line 5:
The problem is that mesage$ is misspelled. The variable
created on line 3 is named message$. The fix is to use
the same variable name in the print statement:
Step 4 — recompile. The build now succeeds:
Step 5 — run and verify:
Then read hello_world_result.txt:
The output is correct. The cycle is complete.
After a clean build, test web programs in a browser. The compiler verifies code correctness, but only the browser reveals user-interface issues such as wrong layout, missing data, broken buttons, or incorrect error messages.
Most web programs begin by making sure the SPINS web server is running:
To run a web program:
The program will print a URL to its GUI console, typically:
Open that URL in a browser and test the main workflow and edge cases:
The full vibe coding cycle is:
.spsrc file.
/validate /build.
One edit, one compile, one test. Keep the loop tight.
call keyword. Invoke routines by name with with and returning.end ___. No braces. for loops close with next varname.select case should include case else.retry re-runs the failing statement. continue skips it. Both are exception-handler keywords only.repeat do for do loops; iterate for for for loops.exit do or exit for. Never break.exit routine. Never return.?. String names end with $.for each, access fields as clustername->field — there is no iterator variable.collect cluster before every for each.findrow() for single-row lookup instead of scanning a whole cluster.VIEW target INTO source, PIECE sep, MATCH n — zero-copy string parsing.sprintf$() formats such as %, %p, %m, and %w.element$() and elements() for delimited strings. Do not invent split().size() for cluster row counts and str$() for number-to-string conversion.pass for operating system commands.cgi://, line input, getsymbol$(), and [[%spscript]] pattern.local routines share the parent's scope. private routines are isolated units with their own parameters.call return throw raise catch except new this null void function def fn break end for endif split.|
Hide Description
|
|
|
Enter or modify the code below, and then click on RUN |
|
Looking for the full power of Sheerpower?
Check out the Sheerpower website. Free to download. Free to use. |