Categories
News

RumiCar Simulator v10.2.0 released

We have released RumiCar Simulator v10.2.0. The release notes below are also available on GitHub.


v10.2.0

Fixed places where the Python-like interpreter for learning programs behaved differently from Python without any error, and places where it raised errors whose cause you could not work out from the message (Stage BJ; the driving physics is untouched — driving on the shipped courses and the result of the shipped official sample race are unchanged; the official sample race’s verifyHash e9f1da0b and the frozen hashes f0–f3 are the same as before, and so is the parse result (syntax tree) of the 26 shipped sample programs). Your program may behave differently — check the lists “forms that ran without error in v10.1.0 but raise an error in v10.2.0” and “forms that gave a value different from Python and now give Python’s value” below. C is unchanged apart from the escapes and CRLF in (1), the line numbers and unterminated strings in (3), the error line of a statement that calls a user function in (4), the errors in (5), and the changed message of the still-unsupported %= (see “Forms whose error message changed” below) (in C, true == 1 is still false and % is still the truncating remainder). (Lexical and syntax error messages are shown in Japanese even in English mode; the quotations in this note are translations.) (1) Lexing and syntax — for i in range(a, b) and range(a, b, step) used to run zero times; fixed (a single argument works as before; four arguments, range(1,2,3,4), are a syntax error). The compound assignments %=, //= and **= are available (py; C’s %= is still unsupported). A compound assignment to a tuple, a, b += 1, is a syntax error (a SyntaxError in Python too). String escapes \n \t \r \\ \" \' \0 are interpreted (py, C, f-strings, #define; in v10.1.0 "a\tb" was “atb”). An unknown escape drops the \ and keeps the next character ("\q" → “q”; Python keeps the two characters \q). Octal \012 is NUL followed by “12”, and \x / \u are not handled. Sources with CRLF line endings (files made on Windows, GitHub import) are accepted (in v10.1.0 a blank line inside a py block gave “unexpected token ‘INDENT'” and a \ line continuation gave “unknown character ””). A line break inside a string in a CRLF source is a single LF (v10.1.0 kept the \r). (2) Operators (py) — % is the floored remainder (-7 % 2 → 1; v10.1.0 gave -1). -x**2 is -(x**2) (-2 ** 2 → -4; v10.1.0 gave 4). True == 1 is true (only == and != compare bools and numbers as numbers). The expressions inside f-string {} are read with Python’s meaning (f"{7//2}" → “3”; v10.1.0 read everything from // on as a comment and gave “7”). f"{'\\n'}" is the two characters \ and n (v10.1.0 gave “n”). Any \ inside an f-string expression that is outside a string literal is a lexical error (f"{d[\"k\"]}", f'{d[\'k\']}', f"{x\t}", f"{x\}" and so on; a SyntaxError in Python too). (3) Triple quotes and line breaks inside strings — """…""" and '''…''' (including the f/F forms) are read as one string (in v10.1.0 s = """a""" was an empty string, and a docstring """say "hi" """ gave “Undefined variable/name: hi”). A line break inside a string advances the line number (error lines and the execution-position display for later statements now point at the real line; C too). Strings inside an f-string expression no longer cut the expression at } or : (f"{':'}" → “:”, f"{'''it's'''}" → “it’s”). Lexical and syntax errors inside an f-string expression report the real line, and a lexical error in a #define replacement body reports the directive’s line. A string left unterminated to the end of the file, and an f-string replacement field without its closing }, are lexical errors. (4) for, loops and functions (py) — after a for loop, the loop variable and variables created in its body can be read (their last values; v10.1.0 gave “Undefined variable/name”). A top-level for overwrites an existing global of the same name (after i = 100, for i in range(3) leaves i at 2; v10.1.0 left 100). Inside a function, the loop variable of a for is local to the function (print(f(), i) goes from 100 100 to 2 100). An assignment to the same name after the loop is also local to the function (the exception to “What did not change” below). A loop variable with the same name as a parameter ends with the loop’s last value (f(9) goes from 9 to 2). A top-level loop variable named like random hides that name after the loop until the program ends. A loop that runs zero times does not create its loop variable. In a while True: program, continue directly in the body ends that pass, and break leaves the loop, runs the statements after the loop once in that pass, and ends the program (nothing happens afterwards; the car keeps its last command, so write a stop command after the loop if you want it to stop; v10.1.0 stopped with “[Runtime error] [object Object]”). One-line forms such as if n == 2: break, else: continue, while x: break, if x: pass, elif …: break, def f(): return 1, def setup(): pass, def f(): global x and if 1: import math work (v10.1.0 gave “Undefined variable/name: break” and the like). The error line and execution-position display of a statement that calls a user function are that statement’s line, not the last line of the called function (x = 10 / f(), for c in f(): and so on; C too). The error line of a statement written on one line is that statement’s line (else: z = 1 / 0 reports the else line). range(a, b, 0) and range(a, b, None) raise “range() step (3rd argument) must not be zero”. (5) break / continue outside a loop and return outside a function — these are now readable errors with a line number (v10.1.0 showed [object Object]: at top level, directly in def loop(): / def setup():, return directly in while True:, a program with neither def loop(): nor while True: that runs once, C’s void loop(){ break; } and a break outside a switch, and so on). break / continue directly in a function called from inside a loop is an error too (in v10.1.0 it silently acted on the caller’s loop; py and C). The error for return outside a function suggests continue to end one pass of a loop and break to leave it (the same wording for py’s while True: and C’s while (1)). Forms that ran without error in v10.1.0 but raise an error in v10.2.0 (all of them are errors in Python too): (a) range(1,2,3,4) (b) a, b += 1 (c) a \ inside an f-string expression outside a string literal (f"{d[\"k\"]}", f'{d[\'k\']}', f"{x\}", f"{x\:>3}") (d) break / continue directly in a function called from inside a loop (py and C) (e) range(a, b, 0), range(a, b, False), range(a, b, None) (f) random.random() after a top-level for random in range(2) (likewise math.sqrt(4) after for math in range(2)) (g) a string left unterminated to the end of the file (s = "abc, s = 'abc, s = """abc, '''It's, s = """a"""", s = "abc\, s = f"{x}, f"{'abc}", f'''{x}, and in C an unused #define S "abc) (h) an f-string replacement field without its closing } (f"{x", f"{x:'>5"; v10.1.0 gave “5”) (i) a syntax error, a \, an unterminated string or a replacement field without its closing } in a triple-quoted f-string, and a runtime error in such an expression (f"""a⏎{1/x}""" after x = 0; v10.1.0 turned the triple-quoted f-string into an empty string and never read the expression) (j) something following a one-line keyword statement on the same line (def f(): return 1 2, def f(): pass 5 in a function that is never called, and if x: break 5 when the condition is false). Forms that were errors and now work in v10.2.0: one-line break / continue / pass / return / global / import; continue / break directly in while True:; the loop variable and body variables after a for; %= / //= / **=; CRLF sources; triple-quoted docstrings that contain quotes. Forms that gave a value different from Python and now give Python’s value (the value changes without any error): range(a, b[, step]); escapes; % with negative numbers; -x**2; True == 1; // in an f-string expression; f"{'\\n'}"; f"{':'}" / f"{'a:b'}" / f"{'}'}"; strings in CRLF sources; triple quotes (s = """a"""); a top-level for and a global of the same name (100 → 2); a for inside a function (print(f(), i) gives 2 100); x = 10 after for x inside a function (the global x goes from 10 to 0); a loop variable with the same name as a parameter (9 → 2); random hidden by a loop variable; a one-line return expression (v10.1.0 evaluated the expression even when the condition was false: if a: return g() called g() while a was false, def f(): return print("side") printed side although f was never called, and a top-level if 0: return g() called g()). A form that gave Python’s value but gives a different value in v10.2.0 (one): in a function that declares global x, making x the loop variable of a for makes the x = 10 after the loop local to the function as well, so the global x does not change (v10.1.0 and Python give 10; v10.2.0 gives 0, because the global statement is skipped). For the same reason, if a function assigns x = 5, then uses x as a for loop variable and assigns x = 10 after the loop, the global x is 10 in v10.1.0 and 5 in v10.2.0 (Python: 0; the x = 5 before the loop overwrites the global, and the x = 10 after the loop is local to the function). Forms whose error message changed: C’s auto s = "abc; and char c = 'a; (syntax error → lexical error “unterminated string”); f"{d["k"]}" (→ “f-string { has no matching }”); f"{x\t}" (“Undefined variable/name: xt” → lexical error); if x: break 5 (when the condition is true: “Undefined variable/name: break” → syntax error; when it is false, v10.1.0 ran it without error — see (j)); C’s a %= 2 (“unexpected token ‘='” → “expected ‘;’ but got ‘%='”; still unsupported); a one-line break / continue / return outside a loop (“Undefined variable/name” → the errors in (5)). What did not change: a name assigned inside a function without global overwrites an existing global of that name (an intentional design; in Python it is local to the function). The exception is the one in (4): a name that became a for loop variable earlier in that function. The differences from Python that Stage BJ did not fix are listed under “Learning-program language semantics” in §9 of the physics model notes (30 items). In addition, the permanent verification gates went from 78 to 79 (wf_bj1_pysem.mjs).


Verifying this release yourself

git clone https://github.com/RumiCar-group/RumiCar-Simulator.git
cd RumiCar-Simulator
node wf_run_all.mjs        # the full assertion-gate suite

The suite runs from a fresh clone with no dependencies beyond Node.js.
The real-browser checks under browser/ additionally need npm install and a display.

How this site is built (v1.4.0)

Some components are open source:

Enjoyed the machinery? The main event is our autonomous-driving simulator — it runs in your browser.
Try the simulator → / GitHub →