ASPL لباتASPL 0.7.0

Search documentation

Search starts with current English documentation · ASPL 0.7.0

Enter a complete name such as read_line, or words about a topic.

    العربية
    Source files

    Open one UTF-8 .aspl or .لبات file, up to 1 MiB, in a new draft. It stays in this browser and does not run automatically.

    One-file quiz

    ASPL 0.7.0 · Current release

    Combine the course concepts in a guided arithmetic quiz with strict input retries.

    On this page

    What you will learn

    Combine question records, a typed list, a helper and strict input into a one-file arithmetic quiz. Build it through four small stages and explain why each run ends.

    Before you begin

    Read loops, functions, text input, numeric parsing, strings, lists, records and recoverable results. The twelve core lessons lead here; virtual files are not needed for this quiz.

    Every source below is a complete independent file. Open it as a new Home draft, then choose Run explicitly. Existing edits remain available. Reading language and source vocabulary do not translate your draft or runtime replies.

    Stage 1: question data and prompts

    The starter prints only 2 + 3?\n, returns status 0 and never reads input. It already supplies all five Question records. Each has prompt: string and answer: i64; list<Question> keeps their fixed order. The expected answers are 5, 5, 12, 4, 15.

    Browser and native · ASPL 0.7.0 · English source

    Execution: Browser and native · ASPL 0.7.0

    Prerequisites:
    • No prior knowledge is required to open and check it.

    Input: No input lines are required.

    record Question { prompt: string, answer: i64 }
    fn start_main() -> i64 {
        let questions: list<Question> = [
            Question { prompt: "2 + 3?", answer: 5 },
            Question { prompt: "9 - 4?", answer: 5 },
            Question { prompt: "3 * 4?", answer: 12 },
            Question { prompt: "12 / 3?", answer: 4 },
            Question { prompt: "7 + 8?", answer: 15 }
        ];
        print(questions[0]::prompt + "\n");
        return 0;
    }
    
    Download quiz-data.aspl

    Expected outcomes
    {
      "browser": {
        "check": "success",
        "class": "success",
        "output": "2 + 3?\n",
        "processStatus": 0
      },
      "native": {
        "check": 0,
        "status": 0,
        "output": "2 + 3?\n"
      }
    }

    Predict the five prompts in order. Change the single print into a loop that prints every prompt. The solution prints exactly 2 + 3?\n9 - 4?\n3 * 4?\n12 / 3?\n7 + 8?\n, returns 0 and reads no input. It displays data, without checking answers or scoring.

    Print all five prompts in their supplied order.

    Hint: Start a mutable index at 0. While it is less than length(questions), print questions[index]::prompt and a newline, then add 1 to index.

    Show worked answer

    The index visits 0 through 4. The strict less-than condition prevents an out-of-bounds access at 5. Each record supplies its prompt text, so print accepts it directly. Incrementing the index makes the loop end. The entry returns normal status 0; no answer has been read or counted.

    Browser and native · ASPL 0.7.0 · English source

    Execution: Browser and native · ASPL 0.7.0

    Prerequisites:
    • No prior knowledge is required to open and check it.

    Input: No input lines are required.

    record Question { prompt: string, answer: i64 }
    fn start_main() -> i64 {
        let questions: list<Question> = [
            Question { prompt: "2 + 3?", answer: 5 },
            Question { prompt: "9 - 4?", answer: 5 },
            Question { prompt: "3 * 4?", answer: 12 },
            Question { prompt: "12 / 3?", answer: 4 },
            Question { prompt: "7 + 8?", answer: 15 }
        ];
        var index: i64 = 0;
        while (index < length(questions)) {
            print(questions[index]::prompt + "\n");
            index = index + 1;
        }
        return 0;
    }
    
    Download quiz-data-solution.aspl

    Expected outcomes
    {
      "browser": {
        "check": "success",
        "class": "success",
        "output": "2 + 3?\n9 - 4?\n3 * 4?\n12 / 3?\n7 + 8?\n",
        "processStatus": 0
      },
      "native": {
        "check": 0,
        "status": 0,
        "output": "2 + 3?\n9 - 4?\n3 * 4?\n12 / 3?\n7 + 8?\n"
      }
    }

    Stage 2: helper and feedback

    The starter calls feedback with 5 and then 6 for the first question. Its is_correct helper deliberately returns false for every answer. It prints Wrong. Expected 5.\nWrong. Expected 5.\n, returns 0 and reads no input. It is a feedback demonstration with an unfinished comparison.

    Browser and native · ASPL 0.7.0 · English source

    Execution: Browser and native · ASPL 0.7.0

    Prerequisites:
    • No prior knowledge is required to open and check it.

    Input: No input lines are required.

    record Question { prompt: string, answer: i64 }
    fn is_correct(question: Question, answer: i64) -> bool {
        return false;
    }
    fn feedback(question: Question, answer: i64) -> unit {
        if (is_correct(question, answer)) {
            print("Correct.\n");
        } else {
            print("Wrong. Expected " + format_i64(question::answer) + ".\n");
        }
    }
    fn start_main() -> i64 {
        let questions: list<Question> = [
            Question { prompt: "2 + 3?", answer: 5 },
            Question { prompt: "9 - 4?", answer: 5 },
            Question { prompt: "3 * 4?", answer: 12 },
            Question { prompt: "12 / 3?", answer: 4 },
            Question { prompt: "7 + 8?", answer: 15 }
        ];
        feedback(questions[0], 5);
        feedback(questions[0], 6);
        return 0;
    }
    
    Download quiz-helper.aspl

    Expected outcomes
    {
      "browser": {
        "check": "success",
        "class": "success",
        "output": "Wrong. Expected 5.\nWrong. Expected 5.\n",
        "processStatus": 0
      },
      "native": {
        "check": 0,
        "status": 0,
        "output": "Wrong. Expected 5.\nWrong. Expected 5.\n"
      }
    }

    is_correct(question: Question, answer: i64) -> bool takes a question value and a numeric reply, then returns a Boolean. feedback returns unit, so callers use it as a statement. Its if chooses immediate feedback; the wrong branch formats the record's expected number. All helpers are top-level in this same file. Predict which line should change when the comparison works.

    Replace the helper's fixed false with a comparison against the question's expected answer.

    Hint: Return answer matches question::answer. Keep both feedback branches and the calls with 5 and 6.

    Show worked answer

    The first call compares 5 with 5 and prints Correct. . The second compares 6 with 5 and prints Wrong. Expected 5. . The complete solution returns status 0 without reading or scoring. The helper returns a Boolean value; that value is separate from the entry's integer process status.

    Browser and native · ASPL 0.7.0 · English source

    Execution: Browser and native · ASPL 0.7.0

    Prerequisites:
    • No prior knowledge is required to open and check it.

    Input: No input lines are required.

    record Question { prompt: string, answer: i64 }
    fn is_correct(question: Question, answer: i64) -> bool {
        return answer matches question::answer;
    }
    fn feedback(question: Question, answer: i64) -> unit {
        if (is_correct(question, answer)) {
            print("Correct.\n");
        } else {
            print("Wrong. Expected " + format_i64(question::answer) + ".\n");
        }
    }
    fn start_main() -> i64 {
        let questions: list<Question> = [
            Question { prompt: "2 + 3?", answer: 5 },
            Question { prompt: "9 - 4?", answer: 5 },
            Question { prompt: "3 * 4?", answer: 12 },
            Question { prompt: "12 / 3?", answer: 4 },
            Question { prompt: "7 + 8?", answer: 15 }
        ];
        feedback(questions[0], 5);
        feedback(questions[0], 6);
        return 0;
    }
    
    Download quiz-helper-solution.aspl

    Expected outcomes
    {
      "browser": {
        "check": "success",
        "class": "success",
        "output": "Correct.\nWrong. Expected 5.\n",
        "processStatus": 0
      },
      "native": {
        "check": 0,
        "status": 0,
        "output": "Correct.\nWrong. Expected 5.\n"
      }
    }

    Stage 3: input, quit and checked parsing

    The starter asks the first question once. It checks exact lowercase q before parse_i64, prints a zero-count early-stop summary for q, prints Parsed: 5\n for 5, or prints Invalid: invalid-number\n for 12x. It then returns 0, even after invalid input. It does not retry, check an answer or score yet. With 12x, then 5 prepared, it consumes only the first line.

    Browser and native · ASPL 0.7.0 · English source

    Execution: Browser and native · ASPL 0.7.0

    Prerequisites:
    • No prior knowledge is required to open and check it.

    Input lines: ["12x"]

    record Question { prompt: string, answer: i64 }
    fn start_main() -> i64 {
        let questions: list<Question> = [
            Question { prompt: "2 + 3?", answer: 5 },
            Question { prompt: "9 - 4?", answer: 5 },
            Question { prompt: "3 * 4?", answer: 12 },
            Question { prompt: "12 / 3?", answer: 4 },
            Question { prompt: "7 + 8?", answer: 15 }
        ];
            print(questions[0]::prompt + " ");
            let line: string = read_line();
            if (line matches "q") {
                print("Stopped early. Correct: 0; answered: 0; total: " + format_i64(length(questions)) + ".\n");
                return 0;
            }
            let parsed: result<i64> = parse_i64(line);
            if (parsed::ok) {
                print("Parsed: " + format_i64(parsed::value) + "\n");
            } else {
                print("Invalid: " + parsed::error::code + "\n");
            }
        return 0;
    }
    
    Download quiz-input.aspl

    Expected outcomes
    {
      "browser": {
        "check": "success",
        "class": "success",
        "output": "2 + 3? Invalid: invalid-number\n",
        "processStatus": 0
      },
      "native": {
        "check": 0,
        "status": 0,
        "output": "2 + 3? Invalid: invalid-number\n"
      }
    }

    Add a pending Boolean loop around the supplied input branches. Only successful parsing sets it false. Predict the first prompt after 12x. The solution repeats 2 + 3? , prints Parsed: 5\n after the next reply 5, and returns 0. Its exact output is 2 + 3? Retry: invalid-number\n2 + 3? Parsed: 5\n. This is still a one-question parsing practice file, with no feedback or score. Its early-stop counts stay zero because this stage counts no answers.

    Retry the same first question after a parsing failure. Stop the practice loop after one parsed number.

    Hint: Start pending as true. Keep q before parsing, read value only when ok, and leave pending unchanged in the error branch. Change the error label from Invalid to Retry.

    Show worked answer

    The failure result has error information but no usable numeric payload. Printing its code leaves pending true, so the same question is requested again. A successful result prints its value and sets pending false. Exact q returns directly before parsing. The entry returns 0 after a number or q, while EOF traps and Stop cancels. No numeric answer contributes to a score in this stage.

    Browser and native · ASPL 0.7.0 · English source

    Execution: Browser and native · ASPL 0.7.0

    Prerequisites:
    • No prior knowledge is required to open and check it.

    Input lines: ["12x","5"]

    record Question { prompt: string, answer: i64 }
    fn start_main() -> i64 {
        let questions: list<Question> = [
            Question { prompt: "2 + 3?", answer: 5 },
            Question { prompt: "9 - 4?", answer: 5 },
            Question { prompt: "3 * 4?", answer: 12 },
            Question { prompt: "12 / 3?", answer: 4 },
            Question { prompt: "7 + 8?", answer: 15 }
        ];
        var pending: bool = true;
        while (pending) {
            print(questions[0]::prompt + " ");
            let line: string = read_line();
            if (line matches "q") {
                print("Stopped early. Correct: 0; answered: 0; total: " + format_i64(length(questions)) + ".\n");
                return 0;
            }
            let parsed: result<i64> = parse_i64(line);
            if (parsed::ok) {
                print("Parsed: " + format_i64(parsed::value) + "\n");
                pending = false;
            } else {
                print("Retry: " + parsed::error::code + "\n");
            }
        }
        return 0;
    }
    
    Download quiz-input-solution.aspl

    Expected outcomes
    {
      "browser": {
        "check": "success",
        "class": "success",
        "output": "2 + 3? Retry: invalid-number\n2 + 3? Parsed: 5\n",
        "processStatus": 0
      },
      "native": {
        "check": 0,
        "status": 0,
        "output": "2 + 3? Retry: invalid-number\n2 + 3? Parsed: 5\n"
      }
    }

    read_line / اقرأ_سطر removes the line terminator and keeps the other text. Use line matches "q" / line يطابق "q" before parsing. Do not trim, normalize digits or fold case. parse_i64 / حلل_ص64 accepts an optional ASCII + or -, then ASCII digits 0 through 9, within the i64 range. +05 and 005 parse as 5; -1 parses as a valid wrong answer in the full quiz. Empty input, 12x, 5, Arabic-Indic ٥, Extended Arabic-Indic ۵ and uppercase Q are invalid-number. 9223372036854775808 is number-out-of-range. Both failures retry unchanged in the solution. See the numeric-text table.

    Only the success branch reads parsed::value / محلل::قيمة; only the failure branch reads parsed::error::code / محلل::الخطأ::الرمز. A parsing failure is recoverable. Close input while waiting supplies EOF and traps with input-exhausted, keeping prior output. Stop reports cancellation and keeps prior output. Neither promises a graceful score summary or normal completion.

    Stage 4: score, advance and summarize

    The starter now asks all five questions, retries invalid input, checks answers and advances after every parsed number. It increments answered and index once, but deliberately leaves correct at zero. Five correct replies print five Correct. lines and Completed. Correct: 0; answered: 5; total: 5.\n. This starter demonstrates an unfinished score, not an accurate result. It supports early quit and returns 0 on completion or q.

    Browser and native · ASPL 0.7.0 · English source

    Execution: Browser and native · ASPL 0.7.0

    Prerequisites:
    • No prior knowledge is required to open and check it.

    Input lines: ["5","5","12","4","15"]

    record Question { prompt: string, answer: i64 }
    fn is_correct(question: Question, answer: i64) -> bool {
        return answer matches question::answer;
    }
    fn summary(label: string, correct: i64, answered: i64, total: i64) -> unit {
        print(label + ". Correct: " + format_i64(correct) + "; answered: " + format_i64(answered) + "; total: " + format_i64(total) + ".\n");
    }
    fn start_main() -> i64 {
        let questions: list<Question> = [
            Question { prompt: "2 + 3?", answer: 5 },
            Question { prompt: "9 - 4?", answer: 5 },
            Question { prompt: "3 * 4?", answer: 12 },
            Question { prompt: "12 / 3?", answer: 4 },
            Question { prompt: "7 + 8?", answer: 15 }
        ];
        let total: i64 = length(questions);
        var index: i64 = 0;
        var answered: i64 = 0;
        var correct: i64 = 0;
        print("Quiz: " + format_i64(total) + " questions. Type q to stop.\n");
        while (index < total) {
            let question: Question = questions[index];
            print("Question " + format_i64(index + 1) + "/" + format_i64(total) + ": " + question::prompt + " ");
            let line: string = read_line();
            if (line matches "q") {
                summary("Stopped early", correct, answered, total);
                return 0;
            }
            let parsed: result<i64> = parse_i64(line);
            if (parsed::ok) {
                if (is_correct(question, parsed::value)) {
                    print("Correct.\n");
                    // Add one to correct here.
                } else {
                    print("Wrong. Expected " + format_i64(question::answer) + ".\n");
                }
                answered = answered + 1;
                index = index + 1;
            } else {
                print("Retry: " + parsed::error::code + ". Use ASCII digits, for example 5, or q.\n");
            }
        }
        summary("Completed", correct, answered, total);
        return 0;
    }
    
    Download quiz-score.aspl

    Expected outcomes
    {
      "browser": {
        "check": "success",
        "class": "success",
        "output": "Quiz: 5 questions. Type q to stop.\nQuestion 1/5: 2 + 3? Correct.\nQuestion 2/5: 9 - 4? Correct.\nQuestion 3/5: 3 * 4? Correct.\nQuestion 4/5: 12 / 3? Correct.\nQuestion 5/5: 7 + 8? Correct.\nCompleted. Correct: 0; answered: 5; total: 5.\n",
        "processStatus": 0
      },
      "native": {
        "check": 0,
        "status": 0,
        "output": "Quiz: 5 questions. Type q to stop.\nQuestion 1/5: 2 + 3? Correct.\nQuestion 2/5: 9 - 4? Correct.\nQuestion 3/5: 3 * 4? Correct.\nQuestion 4/5: 12 / 3? Correct.\nQuestion 5/5: 7 + 8? Correct.\nCompleted. Correct: 0; answered: 5; total: 5.\n"
      }
    }

    total = length(questions) comes from the list. The entry initializes index, answered and correct to zero on every explicit Run. The loop checks index < total before selecting questions[index]. It displays index + 1 for the reader while indexing from zero. A valid wrong answer still increments answered and advances; it never increments correct. Invalid parsing changes none of these three variables. Exact q calls summary before counting the pending question.

    Predict the summary for 5, 5, 0, q before fixing the score. The starter reports zero correct and three answered. Add the missing update only in the matching-answer branch. The complete solution reports two correct, three answered and total five. summary formats printed counts; it returns unit and does not decide the process status. Both normal exit paths explicitly return 0.

    Add one to correct only when the helper says the parsed answer matches. Trace answered and index through an invalid reply, a wrong answer and q.

    Hint: Replace the supplied comment after Correct with correct = correct + 1. Keep answered and index updates after the feedback branches, inside parsed::ok. Leave the failure branch and the q return unchanged.

    Show worked answer

    Only the matching-answer branch increments correct. Both numeric branches then share one answered increment and one index increment. A parsing failure takes neither branch, so it repeats the pending question with unchanged counts. The q branch returns before parsing or those increments. Five correct replies finish at correct 5, answered 5, total 5. After the fifth reply index becomes 5, the loop test is false and the summary prints without another read. The complete one-file solution returns status 0.

    Browser and native · ASPL 0.7.0 · English source

    Execution: Browser and native · ASPL 0.7.0

    Prerequisites:
    • No prior knowledge is required to open and check it.

    Input lines: ["5","5","12","4","15"]

    record Question { prompt: string, answer: i64 }
    fn is_correct(question: Question, answer: i64) -> bool {
        return answer matches question::answer;
    }
    fn summary(label: string, correct: i64, answered: i64, total: i64) -> unit {
        print(label + ". Correct: " + format_i64(correct) + "; answered: " + format_i64(answered) + "; total: " + format_i64(total) + ".\n");
    }
    fn start_main() -> i64 {
        let questions: list<Question> = [
            Question { prompt: "2 + 3?", answer: 5 },
            Question { prompt: "9 - 4?", answer: 5 },
            Question { prompt: "3 * 4?", answer: 12 },
            Question { prompt: "12 / 3?", answer: 4 },
            Question { prompt: "7 + 8?", answer: 15 }
        ];
        let total: i64 = length(questions);
        var index: i64 = 0;
        var answered: i64 = 0;
        var correct: i64 = 0;
        print("Quiz: " + format_i64(total) + " questions. Type q to stop.\n");
        while (index < total) {
            let question: Question = questions[index];
            print("Question " + format_i64(index + 1) + "/" + format_i64(total) + ": " + question::prompt + " ");
            let line: string = read_line();
            if (line matches "q") {
                summary("Stopped early", correct, answered, total);
                return 0;
            }
            let parsed: result<i64> = parse_i64(line);
            if (parsed::ok) {
                if (is_correct(question, parsed::value)) {
                    print("Correct.\n");
                    correct = correct + 1;
                } else {
                    print("Wrong. Expected " + format_i64(question::answer) + ".\n");
                }
                answered = answered + 1;
                index = index + 1;
            } else {
                print("Retry: " + parsed::error::code + ". Use ASCII digits, for example 5, or q.\n");
            }
        }
        summary("Completed", correct, answered, total);
        return 0;
    }
    
    Download quiz-score-solution.aspl

    Expected outcomes
    {
      "browser": {
        "check": "success",
        "class": "success",
        "output": "Quiz: 5 questions. Type q to stop.\nQuestion 1/5: 2 + 3? Correct.\nQuestion 2/5: 9 - 4? Correct.\nQuestion 3/5: 3 * 4? Correct.\nQuestion 4/5: 12 / 3? Correct.\nQuestion 5/5: 7 + 8? Correct.\nCompleted. Correct: 5; answered: 5; total: 5.\n",
        "processStatus": 0
      },
      "native": {
        "check": 0,
        "status": 0,
        "output": "Quiz: 5 questions. Type q to stop.\nQuestion 1/5: 2 + 3? Correct.\nQuestion 2/5: 9 - 4? Correct.\nQuestion 3/5: 3 * 4? Correct.\nQuestion 4/5: 12 / 3? Correct.\nQuestion 5/5: 7 + 8? Correct.\nCompleted. Correct: 5; answered: 5; total: 5.\n"
      }
    }

    Try the distinct outcomes

    The source keeps English output strings in both supplied vocabularies so these exact self-checks apply on either reading page. Correct is the correct-answer count, answered counts valid numeric replies, and total is the question-list length. A printed score is separate from normal process status. There is no pass threshold.

    Replies or control Full solution behavior
    5, 5, 12, 4, 15 Five correct feedback lines, then Completed. Correct: 5; answered: 5; total: 5. and status 0. No sixth prompt or read.
    12x, then 6, then q First question retries with invalid-number; 6 prints Wrong. Expected 5. and advances to question two; q reports Stopped early. Correct: 0; answered: 1; total: 5. with status 0.
    9223372036854775808, then q First question retries with number-out-of-range; early stop reports zero correct and answered, total five, status 0.
    First reply q Stopped early. Correct: 0; answered: 0; total: 5. and status 0.
    5, 5, 0, then q The third reply prints Wrong. Expected 12.; early stop reports two correct, three answered, total five, status 0.
    Close input while waiting input-exhausted trap. Earlier prompts and feedback remain; no graceful EOF summary is guaranteed.
    Stop while waiting Cancellation. Earlier output remains; this is neither EOF nor normal completion.

    After completion, choose Run again to start at question one with zero counts. Saving a source draft saves code, not a score or a suspended run. The quiz uses no modules, native libraries, score files, randomization or timers.

    Optional sixth question

    Add Question { prompt: "10 - 3?", answer: 7 } as a sixth list element in the full solution. Predict the changed total before Run. Submit 5, 5, 12, 4, 15, 7; expect Question 6/6: 10 - 3? Correct.\n and Completed. Correct: 6; answered: 6; total: 6.\n, with status 0 and no seventh read. length(questions) supplies the total, so the loop, prompt denominators and both summaries follow the list. A separate optional challenge is rebuilding the one-file quiz from an empty draft.

    Check your understanding

    Explain why a wrong numeric answer advances but Q retries, why q does not count the pending question, and why closing input cannot promise a score summary. Trace all counters after 12x, 6, 5, q. The summary is zero correct after 6, then one correct and two answered when q ends the run. No grade or progress is stored, and navigation stays open. Return to the Tutorial path.

    Choose where to go next for optional native lessons and practical guides.

    Browse pages