Add Dutch (Nederlands) primitive aliases and localization - #248
Add Dutch (Nederlands) primitive aliases and localization#248laurensWoon wants to merge 22 commits into
Conversation
…GETA/TCSETA ioctls term.c used TCGETA/TCSETA ioctl request codes whenever HAVE_TERMIO_H or HAVE_TERMIOS_H was defined. Those constants exist on Linux (compat with old System V termio) but not on macOS/BSD, which only implement the POSIX termios API via tcgetattr()/tcsetattr(). Split the HAVE_TERMIOS_H case out to use the POSIX calls; the HAVE_TERMIO_H (no termios) fallback keeps using the old ioctl approach unchanged.
Adds Dutch names as additional aliases alongside the existing English primitives (English keeps working unchanged) for turtle graphics, basic control flow, list/word operations, math and I/O -- about 60 primitives, 73 aliases total including short forms (vt/at/re/li/pn/pp/etc, matching UCBLogo's own fd/bk/rt/lt/pd/pu convention). Vocabulary sourced from SuperLogo (1994, Addo Stuur / A.W. Bruna Informatica, based on Comenius Logo) -- extracted via 'strings' from its SLOGO.EXE, the only real historical Dutch Logo dialect I could find (see https://archive.org/details/superlogo-voor-windows for the source software). Full extraction + category breakdown documented separately. Deliberately NOT included yet: the procedure-definition keywords (SuperLogo's possible 'leer'/'doe'/'eind'/'kom') -- Comenius Logo's syntax model isn't confirmed identical to UCBLogo's TO/END, so guessing those risks baking in wrong core-language semantics. Needs verification against the actual running software before adding.
…ved words init.c: adds the procedure-definition and remaining core aliases that were missing from the first batch -- leer (to), alsanders (ifelse), uitvoer/uv (output), bewerk/bw (edit), telherhaal (repcount), toets? (key?), sa (sentence), lw/ll (readword/readlist). logolib/Messages.nl: Dutch translation of UCBLogo's built-in localization file (same format/mechanism as the existing Messages.fr/Messages.sp/ Messages.zh_TW), covering: - all ~73 error/status messages (%p/%s/%t placeholders verified to match the English original exactly, position and count, via a small script -- required for ndprintf's positional substitution to work) - the ~34 reserved words UCBLogo's own translation mechanism supports (to/end/if/ifelse/output/stop/true/false/goto/tag/macro/toplevel/ system/error/nothing + screen/pen/turtle-mode + operator names), which is what makes 'eind' work as a procedure terminator without needing a table entry -- END is recognized structurally via isName() against both the English and this Alt translation, unlike ordinary primitives. This is intentionally NOT a runtime language switch: UCBLogo's Messages mechanism only supports one 'Messages' file per build/distribution (matching how Messages.fr etc. already work), so a Dutch build means installing Messages.nl as 'Messages'. usealternatenames (a buried Logo variable, default false) additionally controls whether generated text (e.g. TRUE/FALSE display, welcome message) shows the Dutch or English variant.
…overflows the 1-byte record_buffer
Root-caused with lldb: any procedure containing 2+ turtle-movement
commands (any combination including FORWARD/BACK) crashed with
EXC_BAD_ACCESS in varTrue(), called from the core evaluator with a
corrupted AllowGetSet pointer (0x0000000200000001).
nographics.h defines GR_SIZE as 1 ("a dummy graphics header file for
computers without graphics"), so graphics.c's
`char record_buffer[GR_SIZE];` is a single byte. safe_to_save() --
called unconditionally from save_line()/save_move()/etc, not gated by
any backend-specific stub -- writes a full 8-byte pointer into that
1-byte buffer on its very first call (`*(char **)(record) = 0;`),
silently corrupting whatever global follows record_buffer in memory
(AllowGetSet, in this build). The corruption doesn't crash immediately;
it surfaces later, on the next unrelated procedure lookup that happens
to consult that now-garbage pointer -- hence the confusing symptom of a
crash on the *second* movement command, or even later, rather than
the first.
FORWARD/BACK are the only two movement primitives that call
forward_helper() (which calls save_line()/save_move()); RIGHT/LEFT do
not, which is why 'right 90 right 90' alone never triggered this.
Fix: make safe_to_save() an unconditional no-op for headless builds,
mirroring the existing HAVE_WX-only early-out in draw_turtle() a few
lines up. There is no window to ever redraw in a headless build, so
recording draw operations for later replay serves no purpose there --
bumping GR_SIZE instead would only move the overflow further out, not
fix the underlying mismatch.
Verified: 'koch 150 4' (256 nested FD/LT/RT calls, previously crashed
immediately) now completes cleanly with a correct final position.
Decompiled logolib/Messages.hlp equivalent -- SLOGO.HLP -- with helpdeco (https://github.com/rofl0r/helpdeco) and found the actual, official 'Woordenlijst van procedures Nederlands-Engels' embedded in the SuperLogo help file. This is authoritative (straight from the product's own documentation) rather than reverse-engineered from strings/usage patterns, and revealed a few mistakes in the earlier batches: Fixes: - laatzien/lz were wrongly aliased to SHOWTURTLE -- the official table says LAATZIEN/LZ -> SHOW (prints a value with brackets preserved, unlike PRINT). Fixed. - kom -> SHOWTURTLE/ST added (this is what laatzien was incorrectly standing in for). - wisscherm/ws (my own invented words for CLEARSCREEN, not sourced) were removed in favor of the authentic wistekening/wt. - welwaar/nietwaar (official terms for TRUE/FALSE) replace the invented waar/onwaar in Messages.nl's reserved-word section. New (doe question from earlier this session, plus the rest of the official table cross-referenced programmatically against this fork's current primitive table): - doe -> RUN (finally resolved -- was left out earlier as unconfirmed) - 57 more primitives with a confirmed UCBLogo equivalent: aantal(count), achtergrond/ag(background), bb/bewerkbestand(editfile), definieer(define), definitie?(defined?), fout(error), graden(heading), gum(penerase), integer(int), kenmerklijst(plist), me/mineerste(butfirst), minlaatste/ml(butlast), naam?(name?), naar(towards), namen(names), neem(ask), neemkenmerk(gprop), opdrachtvenster/ov(textscreen), open(load), opslaan(save), pauze(pause), penomgekeerd(penreverse), pk(pencolor), plaatserachter(lput), plaatservoor(fput), plaatskenmerk(pprop), primitief?(primitive?), printdefinitie(po), printnaarov(type), printperregel(print), printtekst(text), rand(wrap), splitsvenster(splitscreen), teken(char), venster(window), verberg(bury), verbergniet(unbury), verborg(buried), vul(fill), wb/wisbestand(erasefile), wis(erase), wiskenmerk(remprop), wisopdracht/wo(cleartext), wistekening/wt(clearscreen), zag/zetachtergrond(setbackground), zetkleurov(settc), zetcursor(setcursor), zichtbaar?(shown?). ~110 further SuperLogo commands (bitmap/mouse/sound/turtle-shape-editor related, e.g. openbitmap, maakturtle, speelgeluid) have no UCBLogo equivalent -- SuperLogo's Windows GUI has a richer media/object API than UCBLogo's simpler turtle graphics, so these are intentionally not aliased.
…+ fix earlier errors
logolib/Messages.nl existed in the repo but was never listed in dist_logolib_DATA, so `make install` silently skipped it. On this Dutch-localization branch, also copy it over the default Messages file during install so error/status text is actually Dutch by default, matching the reserved-word and command-alias localization already done elsewhere. Found while test-building this branch on Debian (Crostini portability check) -- the app ran but showed English messages despite the wx GUI and Dutch command aliases working.
EDIT/bewerk now opens in a standalone top-level window instead of swapping panels into the main frame, similar to the separate turtle- graphics window and matching how Atari ST Logo's editor worked. Two- phase construction (EditorFrame(wxWindow*) + AttachEditor(TextEditor*)) since the frame and its TextEditor need each other to exist first. Fullscreen-mode fixes (both macOS-specific): - EditorFrame is parented to NULL, not the main LogoFrame -- parenting it to the main window made it a Cocoa child window, which could hang the main window when exiting native fullscreen. - EditorFrame's native NSWindow gets NSWindowCollectionBehaviorFullScreenAuxiliary (via the plain ObjC runtime C API, no separate .mm file needed) so it opens alongside a fullscreen LogoFrame in the same Space instead of getting shunted to the regular desktop, which otherwise left the fullscreen window's focus/cursor broken afterward. Also translated the remaining hardcoded English menu strings to Dutch (File/Edit/Logo/Font menus, the editor's own menu, dialog titles and the Save/Load file-picker) -- these were never covered by any localization system (plain wxWidgets _T() text, not gettext-backed), so this is manual translation like the rest of the Dutch work. Left LogoFrame::SetUpEditMenu() untouched -- confirmed unreferenced dead code from before this window-based editor existed.
Found while comparing our command set against ACSLogo's (a different, more feature-rich macOS-native Logo dialect) at the user's request. These four were genuine gaps, not just naming differences from UCBLogo's existing primitives: - abs/absolutewaarde: no absolute-value primitive existed at all. Implemented as a new opcode in math.c's binary() dispatcher, named labsx (not labs) since labs already exists in <stdlib.h> -- same reason lroundx avoids lround. - tan/tangens: sin, cos and atan (arctangent) existed, but plain tangent did not. - xcor/xcoordinaat, ycor/ycoordinaat: only the combined POS existed (outputting [x y] as a list); these output just one coordinate, mirroring lpos's existing turtle_x/x_scale and turtle_y/y_scale math in graphics.c. Verified via a headless WASM build (today's proof-of-concept setup) with real turtle-position tracking: fd 100 -> xcor 0 / ycor 100, then rt 90 fd 50 -> xcor 50 / ycor 100, matching pos exactly.
openwrite/openread/openappend/openupdate/setwrite/setread/close had no Nederlands alias yet, unlike most other primitives on this branch. Adds openschrijf/openlees/opentoevoeg/openbijwerk/zetschrijf/zetlees/ sluit, documented in NEDERLANDS.md and LOGO-COMMANDOS-NL.md.
emgraphics.h/emgraphics.c/emterm.c implement the EM_GRAPHICS backend that graphics.c has referenced since the WASM/browser proof-of-concept, but which was never actually committed -- the nl branch didn't build with -DEM_GRAPHICS for anyone who didn't already have these files locally. wrksp.c: ledit() gets a new EM_GRAPHICS branch. fork()+execlp() of an external editor process doesn't work for an embedded/app host (no external editor binary, and modern Android blocks exec of anything an app wrote itself); em_edit_file() hands the temp file to the host instead. Android (androidjni.c, not part of this repo) implements this with a real blocking dialog; the WASM backend gets a no-op stub so EDIT behaves like an immediate cancel there rather than failing to link.
Windows and macOS builds were shipping the English logolib/Messages
file, so the startup welcome text and the EDIT template for a new
procedure ('to %p / end') stayed in English even on the nl branch.
Copy Messages.nl over Messages in the install/bundle step so native
builds match the WASM demo's Dutch output.
When a .lg file's final line was the closing 'end'/'eind' of a procedure but had no trailing newline, feof() would already be true right after reading it. The code unconditionally treated that as 'no end line was found' and replaced the just-read line with a synthetic theName(Name_end) placeholder -- an internal name object, not printable text -- silently discarding the real 'eind' line from the procedure's cached body text. Any later SAVE would then write that procedure back out without its closing line. Only synthesize the placeholder when the read genuinely found nothing (car(tnode) == Null_Word), i.e. a truly truncated file missing 'end' entirely -- not whenever feof() merely happens to be set because the real closing line was the last bytes in the file. Verified with a local console (--disable-wx) build: reproduced the bug via lldb (the dropped line resolved to an empty, non-printable node instead of the string "eind"), confirmed the fix restores it, and confirmed both the normal (trailing-newline) case and the genuinely-missing-end fallback still behave as before.
|
If I am understanding this correctly, this will merge in alternative names for logo commands, that are always available. I am not sure I like that. Possibly this might be better if it added a configure flag like '--enable-nl' (or similar, just something that makes sense) and then if that was enabled turn on things like "achtergrond". This is not a hard no, but I would like to think about this more. Possibly an actual aliasing system (or just |
Addresses jrincayc's review comment on jrincayc#248: the ~65 Dutch aliases were unconditionally compiled in, permanently reserving those words even for users who never asked for them. Mirrors the existing --enable-objects pattern exactly (AC_ARG_ENABLE + AC_DEFINE + AM_CONDITIONAL in configure.ac, #ifdef ENABLE_NL around each alias entry in prims[], same grouping convention already used for #ifdef OBJECTS blocks throughout this file). Verified both configurations with a plain --disable-wx build: without the flag, Dutch aliases are unrecognized and English works exactly as before; with the flag, a full recursive Dutch-only procedure (leer/alsanders/uitvoer/eind, with usealternatenames and Messages.nl installed) runs correctly end to end. logolib/Messages.nl is untouched -- it already follows the same opt-in-at-install-time pattern as Messages.fr/.sp/.zh_TW, so it wasn't part of the "always available" concern. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PKfNE3DAacgz89XYkv5gkv
…rincayc#249) # Conflicts: # init.c
|
Added a Without the flag, behavior is unchanged from stock UCBLogo -- the Dutch words aren't recognized as anything, English works exactly as before. With it, everything works as originally submitted, verified with a full recursive Dutch-only procedure (
Didn't attempt the "actual aliasing system" (Logo-level |
Summary
list?/listporfd/forward).fd/bk/rt/lt/pd/pu->vt/at/re/li/pn/pp).logolib/Messages.nl, a full Dutch translation of the existing localization file (same format as the existingMessages.fr/Messages.sp/Messages.zh_TW) -- all ~73 error/status messages plus the ~34 reserved words thetranslations[]/isName()/theName()mechanism supports (to/end/if/ifelse/output/stop/true/false/etc).%p/%s/%tplaceholder count and order verified to match the English original exactly on every line (required forndprintf's positional substitution).NEDERLANDS.md(quick EN/NL lookup table) andLOGO-COMMANDOS-NL.md(each Dutch command with a plain-language Dutch explanation of what it does, not just its English equivalent).Vocabulary source
Sourced from SuperLogo (1994, Addo Stuur / A.W. Bruna Informatica, based on Comenius Logo) -- historically the main Dutch-language Logo implementation, used in Dutch primary education. The software is freely archived at https://archive.org/details/superlogo-voor-windows; the primitive vocabulary was extracted directly from its
SLOGO.EXEviastringsrather than invented for this PR. A few gaps not covered by that source (e.g.laadforload,wisschermforclearscreen) were filled in following the same naming conventions once the SuperLogo source was exhausted.leer/endand thetranslations[]mechanismtois an ordinary primitive ({"to", ..., lto}), soleeris added the same way as every other alias here.end, however, is recognized structurally while parsing a multi-line procedure body (isName(..., Name_end)inwrksp.c), not via the primitive table --isName()always checks both the English name and theAlt(translated) name fromMessages.nlregardless of any setting, soeindworks as a procedure terminator onceMessages.nlis installed, with no separate table entry needed.alsanders(ifelse) is a primitive liketo, added the same way.The Dutch
Messages.nlfile is not runtime-switchable (matching how the existingMessages.fretc. already work --logolib/Messagesis loaded by a fixed filename, there's no language flag), so full Dutch error text requires building/installing withMessages.nlin place ofMessages. The primitive aliases ininit.cwork either way, independent of whichMessagesfile is installed.Deliberately not included
doe/kom(possible extra Comenius Logo structural keywords) are not aliased -- no confirmed UCBLogo equivalent for either.Test plan
Built and ran on macOS (both the console build and the wxWidgets GUI build). Verified:
gelijk? 3 3/equalp 3 3,telop 2 3/sum 2 3,vermenigvuldig 4 5/product 4 5,lijst? [1 2 3]/listp [1 2 3],maak "x 10+ding "x/make "x 10+thing "x,gok 100/random 100.waar/onwaardisplay onceusealternatenamesis set.Messages.nlinstalled asMessages: an unknown-command error prints in Dutch (Ik weet niet hoe ik <naam> moet uitvoeren), and the exit banner prints in Dutch.Built on top of #246 and #247 (portability/bugfixes unrelated to the Dutch work but needed to get a clean macOS build to test against) -- this diff will shrink to just the Dutch-related commits once those land.