File signature
Every .psc file must open with this exact line — it names the file and the flowchart title.
// PSC:1.0 <AlgorithmName>
// PSC:1.0 BubbleSort // Description: Sorts a list of n numbers
Gets this wrong and you'll see E001.
PSC is the pseudocode language PseudoChart reads. You write the steps of an algorithm in plain, structured English; the app turns them into a flowchart. Nothing here executes — PSC describes an algorithm, it does not run one.
Every file needs exactly two things: the signature on line 1, and a named BEGIN … END block. That is already a valid program.
// PSC:1.0 Greeting BEGIN Greeting INPUT "What is your name? " name OUTPUT "Hello, " name END
BEGIN titles the main page of the flowchart. The two can differ.if x > 0
IF x > 0
Keywords are UPPERCASE. Lowercase `if` is just an identifier — the parser will not read it as a branch.
x = 10
LET x = 10
LET is the only way to assign. A bare `=` outside LET is an equality check.
BEGIN
BEGIN Main
BEGIN must be followed by a name — it titles the main page of your flowchart (E015).
BEGIN Main FUNCTION f(a) END FUNCTION END
FUNCTION f(a) END FUNCTION BEGIN Main END
FUNCTION and PROCEDURE live at the top level, never inside a block (E012).
Every .psc file must open with this exact line — it names the file and the flowchart title.
// PSC:1.0 <AlgorithmName>
// PSC:1.0 BubbleSort // Description: Sorts a list of n numbers
Gets this wrong and you'll see E001.
The main algorithm body. BEGIN must be followed by a name — that name titles the main flowchart page.
BEGIN <Name> <statements> END
BEGIN BubbleSort OUTPUT "Starting" END
Gets this wrong and you'll see E015.
Single-line only — starts at // and runs to end of line. There are no block comments.
// <text>
// Full-line comment LET x = 10 // Inline comment
Branch on a condition. ELSE IF and ELSE are optional; only one ELSE, and it must be last.
IF <condition> <statements> ELSE IF <condition> <statements> ELSE <statements> END IF
IF score >= 80 OUTPUT "Pass" ELSE OUTPUT "Fail" END IF
Gets this wrong and you'll see E004 or E014.
Pre-condition loop — if the condition is FALSE the first time, the body never runs.
WHILE <condition> <statements> END WHILE
WHILE swapped = TRUE LET swapped = FALSE END WHILE
Gets this wrong and you'll see E004.
Numeric range loop. Inclusive on both ends, increments by 1.
FOR <variable> FROM <start> TO <end> <statements> END FOR
FOR i FROM 1 TO 5 OUTPUT i END FOR
Gets this wrong and you'll see E007.
Collection loop — assigns each item to the loop variable in turn.
FOR EACH <variable> IN <collection> <statements> END FOR
FOR EACH student IN classList OUTPUT student END FOR
Post-condition loop — the body always runs at least once, then exits when the condition is TRUE.
REPEAT <statements> UNTIL <condition>
REPEAT INPUT guess UNTIL guess = secretNumber
Gets this wrong and you'll see E006.
Each CASE is one line — keyword, value, colon, a single statement. No fall-through, and CASE needs no END.
SWITCH <expression> CASE <value>: <single statement> DEFAULT: <single statement> END SWITCH
SWITCH grade CASE "A": OUTPUT "Excellent" CASE "B": OUTPUT "Good" DEFAULT: OUTPUT "Below average" END SWITCH
Reads a value into a variable. An optional prompt string comes before the variable name.
INPUT <variable> INPUT "<prompt>" <variable>
INPUT age INPUT "Enter your name: " username
Displays values. Several values separated by spaces are concatenated.
OUTPUT <value> OUTPUT "<string>" <variable>
OUTPUT "Hello, world" OUTPUT "Result: " total
The only way to assign. Outside LET, = means equality — LET x = 10 assigns, IF x = 10 compares.
LET <variable> = <expression> LET <collection>[<index>] = <expression>
LET total = 0 LET total = total + price LET list[i] = list[j]
Gets this wrong and you'll see E005.
Read or write one element with [ ], 0-indexed. There is no collection literal syntax.
<collection>[<index>] LET <collection>[<index>] = <expression>
LET first = list[0] LET list[i] = list[j]
Boolean literals — uppercase only. Lowercase true/false are ordinary identifiers.
TRUE | FALSE
LET swapped = TRUE WHILE swapped = TRUE
A named block with no return value. Must sit at the top level — never inside BEGIN…END.
PROCEDURE <name>(<params>) <statements> END PROCEDURE
PROCEDURE printLine(message) OUTPUT ">> " message END PROCEDURE
Gets this wrong and you'll see E012.
A named block that returns a value — needs at least one RETURN. Top level only, like PROCEDURE.
FUNCTION <name>(<params>) <statements> RETURN <expression> END FUNCTION
FUNCTION maximum(a, b)
IF a > b
RETURN a
ELSE
RETURN b
END IF
END FUNCTIONGets this wrong and you'll see E008 or E012.
Runs a PROCEDURE on its own; capture a FUNCTION result with LET x = CALL name(...). Recursion is allowed.
CALL <name>(<arguments>) LET <variable> = CALL <name>(<arguments>)
CALL printLine("Starting")
LET biggest = CALL maximum(x, y)Gets this wrong and you'll see E009 or E010.
Logical operators. Precedence runs NOT, then AND, then OR — use ( ) when in doubt.
<condition> AND <condition> | <condition> OR <condition> | NOT <condition>
IF age >= 18 AND hasTicket = TRUE OUTPUT "Allowed" END IF
= is equality, not assignment. Use != for "not equal".
= != < > <= >=
IF count != 0 LET average = total / count END IF
A bubble sort, using a procedure, a while loop, a for range, a condition and a for-each — paste it into a new file to see the whole flowchart it produces.
// PSC:1.0 BubbleSort
// Description: Sorts a list of n numbers using bubble sort
PROCEDURE swap(list, i, j)
LET temp = list[i]
LET list[i] = list[j]
LET list[j] = temp
END PROCEDURE
BEGIN BubbleSort
INPUT "How many numbers? " n
LET swapped = TRUE
WHILE swapped = TRUE
LET swapped = FALSE
FOR i FROM 1 TO n - 1
IF list[i] > list[i + 1]
CALL swap(list, i, i + 1)
LET swapped = TRUE
END IF
END FOR
END WHILE
OUTPUT "Sorted list:"
FOR EACH item IN list
OUTPUT item
END FOR
ENDThe editor marks problems in the gutter as you type. Here is every code it can show, and what to do about it.
| Code | Trigger | Fix |
|---|---|---|
| E001 | Missing // PSC:1.0 header | Make line 1 exactly `// PSC:1.0 <AlgorithmName>`. |
| E002 | Unknown keyword | Check the spelling — and that it is UPPERCASE. |
| E003 | Unmatched END | An END IF / END WHILE with no opener above it. Remove it, or add the opener. |
| E004 | Unclosed block | An IF / WHILE / FOR was opened but never closed. Add its END line. |
| E005 | Invalid LET assignment | Use `LET <variable> = <expression>` — LET is the only assignment form. |
| E006 | Missing UNTIL after REPEAT | Every REPEAT needs a matching `UNTIL <condition>`. |
| E007 | Invalid FOR range | Use `FOR <var> FROM <start> TO <end>` or `FOR EACH <var> IN <collection>`. |
| E008 | RETURN outside FUNCTION | RETURN only belongs in a FUNCTION. A PROCEDURE returns nothing. |
| E009 | CALL target undefined | Define the FUNCTION or PROCEDURE, or fix the name — it is case-sensitive. |
| E010 | Circular subprocess link | Two files link to each other. Break the loop. |
| E011 | File too large | Max 500 lines or 50 KB. Split the algorithm across linked files. |
| E012 | FUNCTION or PROCEDURE nested inside a block | Move the definition to the top level — before BEGIN or after END. |
| E013 | Empty block body | A block needs at least one statement between its opener and END. |
| E014 | ELSE without IF | ELSE and ELSE IF only follow an IF that is still open. |
| E015 | Missing or unnamed main block | Add `BEGIN <Name>` … `END` — a bare BEGIN with no name is not enough. |
| E016 | Unterminated string literal | Close the quote on the same line — strings never span lines. |
| E017 | Illegal character | Only letters, digits, _, ", operators and brackets are allowed. |
| E018 | Identifier exceeds 64 characters | Shorten the name. |
| E019 | Malformed number | Write 0.5 and 5.0, not .5 or 5. — and never 3.14.15. |
| E020 | Expression nesting deeper than 50 | Split the expression across several LET statements. |