Source code: students.pal
From PROSE Programming Language - Wiki
% % Simple test of data entry via stdin which creates a hierarchy using % classroom subjects and student names % ._init func/def [main], &[.main] func/def [getsubjects], &[.func_subjects] func/def [getstudents], &[.func_students] func/def [getgrades], &[.func_grades] func/def [display], &[.func_display] % % Create top-level containers for the data % reg/load PCTX, ![.prose] obj/def P0 class/add P0, [psContainer] obj/clone P1, P0, P2, P0 obj/commit [school], P0 reg/load P0, ![school] obj/commit P0, [subjects], P1 obj/commit P0, [students], P2 local/rtn .main func/call NULL, [getsubjects] func/call NULL, [getstudents] func/call NULL, [display] func/rtn %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% .func_subjects % % Preparation % reg/load PCTX, ![.prose.school.subjects], P9, ![.prose.sys.io] attr/load P10, [psStreamIn], P11, [psStreamOut], P13, [description] class/load P12, [psContainer] % % Obtain number of subjects from user % reg/load P0, [# of subjects \[1-10\]? ], P1, #1, P2, #10 local/jsr &[.getnumber] reg/load A, #1, P1, P0 op/incr P1 .sbloop % % Get each subject name % reg/copy P0, [Name of subject #], A, [? ] attr/mod P9, P11, P0 attr/copy P0, P9, P10 % % Get rid of newline character at end of input % local/jsr &[.stripnl] % % Make sure there are no dots in the name (keep copy of original) % reg/copy P3, P0 local/jsr &[.stripdots] % % Create a container for this subject % obj/def P7 class/add P7, P12 attr/add P7, P13, P3 obj/commit P0, P7 reg/clr P0 op/incr reg/jmpneq &[.sbloop], A, P1 % % Set flag for getgrades() function to indicate that we are obtaining % grades for the classroom subjects % attr/add ![.prose.school], [description], [0] func/call NULL, [getgrades] func/rtn %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% .func_students % % Preparation % reg/load PCTX, ![.prose.school.students], P9, ![.prose.sys.io] attr/load P10, [psStreamIn], P11, [psStreamOut], P13, [description] class/load P12, [psContainer] % % Obtain number of students % reg/load P0, [# of students \[1-20\]? ], P1, #1, P2, #20 local/jsr &[.getnumber] reg/load A, #1, P1, P0 op/incr P1 .stloop % % Get each student name % reg/copy P0, [Name of student #], A, [? ] attr/mod P9, P11, P0 attr/copy P0, P9, P10 % % Get rid of newline character at end of input % local/jsr &[.stripnl] % % Make sure there are no dots in the name (keep copy of original) % reg/copy P3, P0 local/jsr &[.stripdots] % % Create a container for this student % obj/def P7 class/add P7, P12 attr/add P7, P13, P3 obj/commit P0, P7 reg/clr P0 op/incr reg/jmpneq &[.stloop], A, P1 % % Set flag for getgrades() function to indicate that we are obtaining % grades for the classroom subjects % attr/mod ![.prose.school], [description], [1] func/call NULL, [getgrades] func/rtn %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% .func_grades % % Preparation % reg/load PCTX, ![.prose.school], P9, ![.prose.sys.io] attr/load P10, [psStreamIn], P11, [psStreamOut], P12, [description] % % Read flag to determine which branch we're grading % attr/test PCTX, [description], [0] reg/jmpeq &[.grade1], SCMP, #1 % % We're processing the students % reg/load PCTX, ![students] reg/load P8, [Student: ] local/jmp &[.grade2] % % We're processing the subjects % .grade1 reg/load PCTX, ![subjects] reg/load P8, [Subject: ] .grade2 % % Iterate each node on the branch % reg/load P0, (PCTX) attr/mod P9, P11, [\n] .gdloop reg/load P1, (P0) reg/jmpeq &[.gdexit], P1, NULL attr/copy P2, P1, P12 reg/copy P2, P8, P2, [\n] attr/mod P9, P11, P2 % % Obtain a grade for this subject or student % stack/push P0, P1 reg/load P1, #1, P2, #4, P0, [Grade 1) Beginner, 2) Intermediate, 3) Advanced, 4) Postgrad \[1-4\]? ] local/jsr &[.getnumber] % % Force .gdset label to be given an index number now % noop &[.gdset] % % Jump to correct code section based upon selection % reg/index A, &[.gdjmp1] op/decr P0 opa/add P0 stack/pull P1, P0 reg/load P2, (#0, A) local/jmp P2 .gdjmp1 stack/push [Beginner] local/jmp &[.gdset] .gdjmp2 stack/push [Intermediate] local/jmp &[.gdset] .gdjmp3 stack/push [Advanced] local/jmp &[.gdset] .gdjmp4 stack/push [Postgrad] .gdset % % Add an additional description attribute % reg/copy P2, [Grade: ], PULL attr/mvadd P1, P12, P2 local/jmp &[.gdloop] .gdexit func/rtn %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% .func_display % % Preparation % reg/load PCTX, ![.prose.school], P9, ![.prose.sys.io] attr/load P11, [psStreamOut], P12, [description] % % Process each subject, and then list the students at the same grade % attr/mod P9, P11, [------------------------------------------------------------------------------\n] reg/load P0, (![subjects]) .dloop reg/load P1, (P0) reg/jmpeq &[.dexit], P1, NULL % % Read both values from description (one is display name, one is the grade) % local/jsr &[.getdesc] reg/copy P3, [Subject: ], P3, [\n] attr/mod P9, P11, P3 reg/copy P5, P4, [\n] attr/mod P9, P11, P5 % % Display all students at this grade % reg/load P6, (![students]) reg/load A, #0 reg/move P8, P4 .dloop2 reg/load P1, (P6) reg/jmpeq &[.dcont], P1, NULL % % Read both values from description (one is display name, one is the grade) % local/jsr &[.getdesc] reg/jmpneq &[.dnext], P4, P8 % % Display list of students on one line (comma-separated) % reg/jmpneq &[.dcomma], A, #0 reg/copy P3, [Students: ], P3 local/jmp &[.dstu] .dcomma reg/copy P3, [, ], P3 .dstu attr/mod P9, P11, P3 op/incr .dnext reg/clr P3, P4 local/jmp &[.dloop2] .dcont reg/clr P3, P4, P6, P8 attr/mod P9, P11, [\n\n] local/jmp &[.dloop] .dexit func/rtn %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% .stripdots % % Remove dots from text in P0 % stack/push A, P1, P2, P3, P4 % % Read length of text string and process 4 bytes at a time % reg/xload P1, (P0) reg/load A, #0 .strip_loop reg/load P2, (P0, A) op/and P3, P2, #0xff000000 reg/jmpneq &[.strip2], P3, #0x2e000000 op/and P2, P2, #0x00ffffff op/or P2, P2, #0x5f000000 reg/load P4, #1 .strip2 op/and P3, P2, #0x00ff0000 reg/jmpneq &[.strip3], P3, #0x002e0000 op/and P2, P2, #0xff00ffff op/or P2, P2, #0x005f0000 reg/load P4, #1 .strip3 op/and P3, P2, #0x0000ff00 reg/jmpneq &[.strip4], P3, #0x00002e00 op/and P2, P2, #0xffff00ff op/or P2, P2, #0x00005f00 reg/load P4, #1 .strip4 op/and P3, P2, #0x000000ff reg/jmpneq &[.strip5], P3, #0x0000002e op/and P2, P2, #0xffffff00 op/or P2, P2, #0x0000005f reg/load P4, #1 .strip5 reg/jmpneq &[.strip_next], P4, #1 % % Save new 4-byte sequence back over original text (replacing . for _) % reg/save P0, (P2, A) .strip_next opa/add #4 reg/cmp P1, A reg/jmpeq &[.strip_loop], SCMP, #2 stack/pull P4, P3, P2, P1, A local/rtn %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% .stripnl % % Remove newline from end of text in P0 % stack/push A, P1, P2 reg/xload P1, (P0) op/decr P1 reg/load P2, (P0, P1) reg/jmpneq &[.stripnl2], P2, #0x0a000000 reg/save P0, (P1) .stripnl2 stack/pull P2, P1, A local/rtn %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% .getnumber % % Get number from user (prompt in P0, base P1, top P2) % Result is returned in P0 % reg/load PUSH, P3, P3, P0 .gnget attr/mod P9, P11, P3 attr/copy P0, P9, P10 reg/conv P0, P0 reg/cmp P0, P1 reg/jmpeq &[.gnget], SCMP, #2 reg/cmp P0, P2 reg/jmpeq &[.gnget], SCMP, #4 attr/mod P9, P11, [\n] stack/pull P3 local/rtn %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% .getdesc % % Read both values from description (one is display name, one is the grade) % Will return display name in P3 and grade in P4 % attr/copy P2, (P1, P12) attr/copy P3, (P2) attr/copy P4, (P2) reg/clr P2 reg/xscan P2, P3, [Grade: ] reg/jmpneq &[.gdret], P2, #0 % % Swap P3 and P4 % reg/move P5, P3, P3, P4, P4, P5 .gdret local/rtn