diff --git a/.gitmodules b/.gitmodules index 34db7731..f4e85444 100644 --- a/.gitmodules +++ b/.gitmodules @@ -839,3 +839,6 @@ [submodule "vendor/grammars/language-jolie"] path = vendor/grammars/language-jolie url = https://github.com/fmontesi/language-jolie +[submodule "vendor/grammars/Sublime-Pep8"] + path = vendor/grammars/Sublime-Pep8 + url = https://github.com/R4PaSs/Sublime-Pep8 diff --git a/grammars.yml b/grammars.yml index 604d5bbe..da835b01 100755 --- a/grammars.yml +++ b/grammars.yml @@ -100,6 +100,8 @@ vendor/grammars/Sublime-Modula-2: - source.modula2 vendor/grammars/Sublime-Nit: - source.nit +vendor/grammars/Sublime-Pep8/: +- source.pep8 vendor/grammars/Sublime-QML: - source.qml vendor/grammars/Sublime-REBOL: diff --git a/lib/linguist/languages.yml b/lib/linguist/languages.yml index 707ca67e..9d4c0421 100755 --- a/lib/linguist/languages.yml +++ b/lib/linguist/languages.yml @@ -3160,6 +3160,14 @@ Pascal: codemirror_mode: pascal codemirror_mime_type: text/x-pascal language_id: 281 +Pep8: + type: programming + color: "#C76F5B" + extensions: + - ".pep" + ace_mode: text + tm_scope: source.pep8 + language_id: 840372442 Perl: type: programming tm_scope: source.perl diff --git a/samples/Pep8/div.pep b/samples/Pep8/div.pep new file mode 100644 index 00000000..19e0084b --- /dev/null +++ b/samples/Pep8/div.pep @@ -0,0 +1,34 @@ +main: SUBSP 8, i + DECI 0, s + DECI 2, s + CALL div + DECO 4, s + CHARO '\n', i + DECO 6, s + CHARO '\n', i + STOP + +; Divides two numbers following the euclidian method +; +; Parameters: +; SP + 2: Dividend +; SP + 4: Divider +; Returns: +; SP + 6: Quotient +; SP + 8: Remain +div: LDX 0, i + LDA dividend, s +divlp: CPA divider, s + BRLT divout + ADDX 1, i + SUBA divider, s + BR divlp +divout: STX quot, s + STA rem, s + RET0 +dividend: .EQUATE 2 +divider: .EQUATE 4 +quot: .EQUATE 6 +rem: .EQUATE 8 + + .END diff --git a/samples/Pep8/flag.pep b/samples/Pep8/flag.pep new file mode 100644 index 00000000..fbd76376 --- /dev/null +++ b/samples/Pep8/flag.pep @@ -0,0 +1,23 @@ +_start: LDA 0,i + LDX 0,i + LDA 20, i + ADDA 51, i + CPA 0,i + BRLT s3 + BR s4 +s1: LDBYTEA s3, x + NOTA + STBYTEA s3, x + ADDX 1,i + CPX 12, i + BRNE s1 +s2: STOP +s4: LDA 31, d + LDX 50, d + RET0 + STOP +s3: CPX -27746, d + ANDX -8241, i + SUBA -12337, sxf + LDX -12289, sx + .END diff --git a/samples/Pep8/linked.pep b/samples/Pep8/linked.pep new file mode 100644 index 00000000..cb63f5a9 --- /dev/null +++ b/samples/Pep8/linked.pep @@ -0,0 +1,675 @@ +; Linked list of integers API +; +; Contains the basis of the structure and a +; variety of available functions to call on it. +; +; Calling conventions: +; +; - When the number of arguments is <= 2, the fastcall convention will be used: +; Arguments will be passed by registers, no assumption is made concerning the +; state of the registers during execution, they will need to be saved. +; +; - When the number of arguments exceeds 2, the cdecl convention will be used: +; Arguments will be passed on the stack, no assumption is made concerning the +; state of the registers during execution, they will need to be saved. + +; Simple test program, do no include when using the library +main: SUBSP 4, i + DECI mnelmt, s + CALL newlst + LDX mnlst, s + CALL lstgetst + LDX mnlst, s + CALL lstsetst + LDX mnlst, s + CALL lstgetst + LDX mnlst, s + CALL shftest + LDX mnlst, s + CALL ushftest + LDX mnlst, s + CALL shftest + ADDSP 4, i + STOP +; Pointer to the list +mnlst: .EQUATE 0 +; Element read +mnelmt: .EQUATE 2 + +; TESTS + +; Simple test for the get operation +; Gets the first element of the list and prints it +; +; REQUIRES: Non-empty list +; +; Parameters: +; - X: Pointer to the list +; +; Returns: +; void +lstgetst: SUBSP 2, i + LDA 0, i + CALL lstget + STA 0, s + DECO 0, s + CHARO '\n', i + ADDSP 2, i + RET0 + +; Test for the set operation +; Sets the first element of the list to a given value +; The value is read from stdin +; +; REQUIRES: Non-empty list +; +; Parameters: +; - X: Pointer to the list +; +; Returns: +; void +lstsetst: SUBSP 6, i + STX 0, s + DECI 4, s + LDA 0, i + STA 2, s + CALL lstset + ADDSP 6, i + RET0 + +; Tests shift operation on a list +; Gets the last element of the list and prints it +; +; REQUIRES: Non-empty list +; +; Parameters: +; - X: Pointer to the list +; +; Returns: +; void +shftest: SUBSP 2, i + CALL lstshft + STA 0, s + DECO 0, s + CHARO '\n', i + ADDSP 2, i + RET0 + +; Tests unshift operation on a list +; Unshifts a new element read from keyboard +; +; Parameters: +; - X: Pointer to the list +; +; Returns: +; void +ushftest: SUBSP 2, i + DECI 0, s + LDA 0, s + CALL lstunshf + ADDSP 2, i + RET0 + +; LIBRARY + +; Creates a new list with `element` as head +; +; Parameters: +; SP + 4: Element +; +; Returns: +; SP + 2: Pointer to the list +newlst: LDA lstlen, i + CALL new + STX 2, s + CALL newnode + SUBSP 2, i + STX 0, s + LDX nodeelmt, i + LDA 6, s + STA 0, sxf + LDA 0, s + LDX lsthead, i + STA 4, sxf + ADDSP 2, i + RET0 + +; Gets a node at specified index in a list +; +; Parameters: +; - A: Index +; - X: Pointer to the list +; +; Returns: +; - A: Error code (0 if no error was produced) +; - X: Pointer to the node +; +; Errors: +; -1: Index < 0 +; -2: Index >= list.length +nodeat: SUBSP 10, i + STA ndaind, s + STX ndalst, s + LDX lsthead, i + LDA ndalst, sxf + STA ndanode, s + LDA ndaind, s + CPA 0, i + LDA 0, i + STA ndacurri, s + BRGE ndagez + LDA -1, i + ADDSP 10, i + RET0 +ndagez: LDX ndalst, s + CALL listlen + STA ndalstln, s + LDA ndaind, s + CPA ndalstln, s + BRLT ndalp + LDA -2, i + ADDSP 10, i + RET0 +ndalp: LDA ndacurri, s + CPA ndaind, s + BREQ ndaout + LDX nodenxt, i + LDA ndanode, sxf + STA ndanode, s + LDA ndacurri, s + ADDA 1, i + STA ndacurri, s + BR ndalp +ndaout: LDX ndanode, s + LDA 0, i + ADDSP 10, i + RET0 +ndaind: .EQUATE 0 +ndanode: .EQUATE 2 +ndalst: .EQUATE 4 +ndalstln: .EQUATE 6 +ndacurri: .EQUATE 8 + +; Length of the list passed as a parameter +; +; Parameters: +; - X: List +; +; Returns: +; - A: Length +listlen: SUBSP 4, i + STX lenode, s + LDX lenode, sf + STX lenode, s + LDA 0, i + STA lencpt, s +llenlp: LDA lenode, s + CPA 0, i + BREQ lenout + LDA lencpt, s + ADDA 1, i + STA lencpt, s + LDX nodenxt, i + LDA lenode, sxf + STA lenode, s + BR llenlp +lenout: LDA lencpt, s + ADDSP 4, i + RET0 +lenode: .EQUATE 0 +lencpt: .EQUATE 2 + +; Gets an element in a list at a specified index +; +; Parameters: +; - A: Index +; - X: Address of the list +; +; Returns: +; - A: Element value +; +; Error: +; If out of bounds, prints an error message and stops the program +lstget: SUBSP 2, i + STA 0, s + CALL nodeat + CPA 0, i + BRNE getoob + LDA 0, x + ADDSP 2, i + RET0 +; Out of bounds +getoob: STRO getstrob, d + DECO 0, s + CHARO '\n', i + STOP +; String for out of bounds error +getstrob: .ASCII "Invalid index on get, index = \x00" + +; Sets an element in a list at a specified index to a new value +; +; Parameters: +; - SP + 2: Pointer to the list +; - SP + 4: Index +; - SP + 6: Element +; +; Returns: +; - A: 0 if all went well, an error code otherwise (analogous to the error codes in nodeat) +lstset: CHARO '\n', i + DECO lstsetlp, s + CHARO ' ', i + DECO lstsetin, s + CHARO ' ', i + DECO lstsetel, s + CHARO '\n', i + SUBSP 2, i + LDX lstsetlp, s + LDA lstsetin, s + CALL nodeat + CPA 0, i + BRNE lstsetrt + STX lstsetnp, s + LDA lstsetel, s + LDX nodeelmt, i + STA lstsetnp, sxf + LDA 0, i +lstsetrt: ADDSP 2, i + RET0 +; Pointer to the list +lstsetlp: .EQUATE 4 +; Element to set the value at +lstsetel: .EQUATE 8 +; Index of the node +lstsetin: .EQUATE 6 +; Pointer to the node +lstsetnp: .EQUATE 0 + +; Removes the first element of the list in parameter and returns its value +; +; REQUIRES: Non-empty list +; +; Parameters: +; ⁻ X: Pointer to the list +; +; Returns : +; - A: Element removed +lstshft: SUBSP 8, i + STX lshflp, s + LDX lsthead, i + LDA lshflp, sxf + CPA 0, i + BREQ shfterr + STA lshfohd, s + LDX nodenxt, i + LDA lshfohd, sxf + STA lshfnhd, s + LDX lsthead, i + STA lshflp, sxf + LDX nodeelmt, i + LDA lshfohd, sxf + ADDSP 8, i + RET0 +shfterr: STRO shfterrm, d + STOP +; Pointer to the list +lshflp: .EQUATE 0 +; Pointer to the old head +lshfohd: .EQUATE 2 +; Old head's element +lshfhdel: .EQUATE 4 +; Pointer to the new head +lshfnhd: .EQUATE 6 +; Error message on shift +shfterrm: .ASCII "Cannot do shift on empty list.\n\x00" + +; Inserts a new element at the beginning of a list +; +; Parameters: +; - X: Pointer to the list +; - A: Element to add to the list +; +; Returns: +; - A: Error code, 0 if all right, a code otherwise +lstunshf: SUBSP 8, i + STA lunshelm, s + STX lunslp, s + CALL newnode + STX lunsnhd, s + LDX lsthead, i + LDA lunslp, sxf + STA lunsohd, s + LDX nodenxt, i + LDA lunsohd, s + STA lunsnhd, sxf + LDA lunshelm, s + LDX nodeelmt, i + STA lunsohd, sxf + LDX lsthead, i + LDA lunsnhd, s + STA lunslp, sxf + ADDSP 8, i + RET0 +; Pointer to the list +lunslp: .EQUATE 0 +; Pointer to the old head +lunsohd: .EQUATE 2 +; Pointer to the new head +lunsnhd: .EQUATE 4 +; Element to add +lunshelm: .EQUATE 6 + +; Finds whether or not an element is present in a list +; +; Parameters: +; - X: Pointer to the list +; - A: Element to be found +; +; Returns: +; - A: 0 if element was not found, 1 if it was +lstfnd: SUBSP 6, i + STX lstfndlp, s + STA lstfndel, s + LDX lsthead, i + LDA lstfndlp, sxf + STA lstfndnd, s +fndloop: CPA 0, i + BREQ notfnd + LDX nodeelmt, i + LDA lstfndnd, sxf + CPA lstfndel, s + BREQ found + LDX nodenxt, i + LDA lstfndnd, sxf + STA lstfndnd, s + BR fndloop +notfnd: LDA 0, i + ADDSP 6, i + RET0 +found: LDA 1, i + ADDSP 6, i + RET0 +; Pointer to the list +lstfndlp: .EQUATE 0 +; Element to search +lstfndel: .EQUATE 2 +; Current node +lstfndnd: .EQUATE 4 + +; Pushes a new element at the end of the list +; +; Parameters: +; - X: Pointer to the list +; - A: Element to push +; +; Returns: +; - A: 0 if all went well, an error code otherwise +lstpsh: SUBSP 8, i + STX lpshlp, s + STA lpshel, s + CALL newnode + STX lpshnd, s + LDX lpshlp, s + CALL listlen + CPA 0, i + BREQ lpshshft + SUBA 1, i + LDX lpshlp, s + CALL nodeat + STX lpshlnd, s + LDX nodenxt, i + LDA lpshnd, s + STA lpshlnd, sxf + LDA lpshel, s + LDX nodeelmt, i + STA lpshnd, sxf + ADDSP 8, i + RET0 +lpshshft: LDX lpshlp, s + LDA lpshel, s + CALL lstunshf + ADDSP 8, i + RET0 +; Pointer to the list +lpshlp: .EQUATE 0 +; Element to add to the list +lpshel: .EQUATE 2 +; Node to add to the list +lpshnd: .EQUATE 4 +; Node to append +lpshlnd: .EQUATE 6 + +; Pops the last element of a list +; +; Parameters: +; - X: Pointer to the list +; +; Returns: +; - A: Element removed from the list +lstpop: SUBSP 6, i + STX lpoplp, s + CALL listlen + CPA 0, i + BRNE poperrem + CPA 1, i + BREQ popshft + SUBA 2, i + LDX lpoplp, s + CALL nodeat + STX lpopndpr, s + LDX nodenxt, i + LDA lpopndpr, sxf + LDA 0, i + LDX nodenxt, i + STA lpopndpr, sxf + STA lpoplnd, s + LDX nodeelmt, i + LDA lpoplnd, s + ADDSP 6, i + RET0 +poperrem: STRO poperrsm, d + STOP +popshft: LDX lpoplp, s + CALL lstshft + ADDSP 6, i + RET0 +; Pointer to the list +lpoplp: .EQUATE 0 +; Node to remove +lpoplnd: .EQUATE 2 +;New last node +lpopndpr: .EQUATE 4 +; Message to print when popping an empty list +poperrsm: .ASCII "Error: cannot pop an empty list.\n\x00" + +; Inserts an element in a list at a given position +; +; REQUIRES: Non-empty list +; +; Parameters: +; - SP + 2: Pointer to the list +; - SP + 4: Index to insert at +; - SP + 6: Element to add +; +; Returns: +; - A: Error code: 0 if all went well, -1 if index < 0, -2 if index > list.length +lstinsat: SUBSP 6, i + LDA lstinsid, s + CPA 0, i + BRLT lstinslz + BREQ lstinush + LDX lstinslp, s + CALL listlen + CPA lstinsel, s + BRLT lstinsgl + BREQ lstinpsh + LDX lstinslp, s + LDA lstinsel, s + SUBA 1, i + CALL nodeat + STX lstinsnd, s + LDX nodenxt, i + LDA lstinsnd, sxf + STA lstinscx, s + CALL newnode + STX lstinscn, s + LDX nodeelmt, i + LDA lstinsel, s + STA lstinscn, sxf + LDX nodenxt, i + LDA lstinscx, s + STA lstinscn, sxf + LDA lstinscn, s + LDX nodenxt, i + STA lstinsnd, sxf + ADDSP 6, i + RET0 +lstinush: LDX lstinslp, s + LDA lstinsel, s + CALL lstunshf + ADDSP 6, i + RET0 +lstinpsh: LDX lstinslp, s + LDA lstinsel, s + CALL lstpsh + ADDSP 6, i + RET0 +; Insert with index < 0 +lstinslz: LDA -1, i + ADDSP 6, i + RET0 +; Insert with index > list.length +lstinsgl: LDA -2, i + ADDSP 6, i + RET0 +; List pointer +lstinslp: .EQUATE 8 +; Index of the newly created node +lstinsid: .EQUATE 10 +; Element to add +lstinsel: .EQUATE 12 +; Node to change the pointer to the next +lstinsnd: .EQUATE 0 +; Node to insert +lstinscn: .EQUATE 2 +; Pointer to the node after the created one (might be null) +lstinscx: .EQUATE 4 + +; Removes a node at a given index in a list, +; returns the element previously contained +; +; Parameters: +; - X: Pointer to the list +; - A: Index of the element +; +; Returns: +; - A: Element removed +; +; Error: +; In case of error, the program aborts with an error message +lstremat: SUBSP 8, i + STX lremlp, s + STA lremid, s + CPA 0, i + BRLT lstremob + BREQ lstremz + CALL listlen + CPA lremid, s + BRGE lstremob + SUBA 1, i + CPA lremid, s + BREQ lrempop + LDA lremid, s + LDX lremlp, s + CALL nodeat + STX lremnd, s + LDA lremid, s + SUBA 1, i + LDX lremlp, s + CALL nodeat + STX lrempnd, s + LDX nodenxt, i + LDA lremnd, sxf + STA lrempnd, sxf + LDX nodeelmt, i + LDA lremnd, sxf + ADDSP 8, i + RET0 +lstremz: LDX lremlp, s + CALL lstshft + ADDSP 8, i + RET0 +lrempop: LDX lremlp, s + CALL lstpop + ADDSP 8, i + RET0 +lstremob: STRO lremobst, d + DECO lremid, s + CHARO '\n', i + STOP +; Pointer to the list +lremlp: .EQUATE 0 +; Index to remove an element at +lremid: .EQUATE 2 +; Pointer to the node before the removed element +lrempnd: .EQUATE 4 +; Pointer to the node to remove +lremnd: .EQUATE 6 +; Error out of bounds string for remove_at +lremobst: .ASCII "Error: Out of bounds in remove_at, index = \x00" + +; Creates a new node from scratch +; Sets its content to 0/NULL +; +; Parameters: +; void +; +; Return: +; - X: Address of the node +newnode: LDA nodeln, i + SUBSP 2, i + CALL new + STX 0, s + LDA 0, i + LDX nodenxt, i + STA 0, sxf + LDX nodeelmt, i + STA 0, sxf + LDX 0, s + ADDSP 2, i + RET0 + +; Allocates a new structure in the heap +; +; Parameters: +; - A: Length of the structure to allocate (bytes) +; +; Returns: +; - X: Address of the allocated structure +new: ADDA hpptr, d + LDX hpptr, d + STA hpptr, d + RET0 + +; Node in a linked list +; +; Contains two fields: +; - Element: Offset 0 +; - Next: Offset 2 +; +nodeln: .EQUATE 4 +nodeelmt: .EQUATE 0 +nodenxt: .EQUATE 2 + +; Linked list capsule +; +; Contains one field: +; - Head: Offset 0 +; +lstlen: .EQUATE 2 +lsthead: .EQUATE 0 + +; Pointer to the next available byte on the heap +hpptr: .ADDRSS heap +; Start of the heap +heap: .BLOCK 1 + .END diff --git a/samples/Pep8/msq.pep b/samples/Pep8/msq.pep new file mode 100644 index 00000000..0bf7b93d --- /dev/null +++ b/samples/Pep8/msq.pep @@ -0,0 +1,434 @@ +; Reads a square from stdin, then computes whether it is a magic square or not. +; +; A Magic Square is a square following a specific set of rules, namely: +; - The sum of each row must be the same as the sum of the diagonal +; - The sum of the anti-diagonal must be the same as the sum of the diagonal +; - The sum of each column must be the same as the sum of the diagonal +; +; If any column, row, or anti-diagonal does not follow the aformented rules, +; the program will output its number to stdout. +; +; Columns are identified by a negative digit, ranging from -1 to -n +; The anti-diagonal is identified by the number 0. +; Finally, rows are identified by a positive integer, ranging from 1 to n. +; +; Formatting: +; First a number `n` is read from Stdin, it will determine the size of the square +; Then, enter the data for the square, `n` entries will be read +; The data is sequentially added to the square in memory, from the upper-left corner +; to the lower-right corner, in a zig-zag pattern +; +; Example: +; 3 +; 4 9 3 +; 3 5 7 +; 8 1 6 +; +; Limitation: Since there is no dynamic allocation, the size +; of the square is capped at a maximum of 32*32. +; Any size lower than 1 or higher than 32 will produce +; an error and the termination of the program. + +;_start + DECI sidelen, d + LDA sidelen, d + CPA 1, i + BRLT sderror + CPA 32, i + BRGT sderror + LDX sidelen, d + CALL mult + STA sqlen, d + CALL fillsq + LDA sidelen, d + LDX square, i + CALL diagsum + STA dgsm, d + CALL colsums + LDA sidelen, d + LDX square, i + CALL cdiagsum + CPA dgsm, d + BREQ cnt + DECO 0, i + CHARO '\n', i +cnt: STA cdsm, d + CALL rowsums + STOP +el: .BLOCK 2 +; Length of a side of the square +sidelen: .WORD 0 +; Total length of the square +sqlen: .BLOCK 2 +; 32 * 32 square of integers +square: .BLOCK 255 + .BLOCK 255 + .BLOCK 255 + .BLOCK 255 + .BLOCK 255 + .BLOCK 255 + .BLOCK 255 + .BLOCK 255 + .BLOCK 8 + +; Prints an error and terminates the program +sderror: STRO stderr, d + STOP + +; Parameters: A: Size of a side of the square +; X: Base address of the square +; cscolid: Identifier of the column (0-based) + +; Computes the sum of each column +; If the sum is not the same as dgsm, its index will be printed (in negative form) +; +; Parameters: A: Size of a side of the square +; X: Address of the square +; +; Return: void +colsums:STA clsmsqsz, d + STX clsmsqad, d + SUBA 1, i + STA clsmyp, d +clssmlp:CPA 0 ,i + BRLT clsmout + STA cscolid, d + LDA clsmsqsz, d + LDX clsmsqsz, d + CALL colsum + CPA dgsm, d + BREQ clsdecpt + LDX clsmyp, d + NEGX + STX clsmyp, d + DECO clsmyp, d + CHARO '\n', i + LDX clsmyp, d + NEGX + STX clsmyp, d +clsdecpt: LDA clsmyp, d + SUBA 1, i + STA clsmyp, d + BR clssmlp +clsmout: RET0 +clsmsqad: .BLOCK 2 +clsmsqsz: .BLOCK 2 +clsmyp_: .BLOCK 2 + +; Compute the sum of each row +; Prints its index if the value does not match dgsum +; +; Parameters: A: Size of a side of the square +; X: Address of the square +; +; Returns: void +rowsums: STA maxrows, d + STX rowssqad, d + LDA 0, i + STA tmprwsm, d + STA rowid, d +rwsmslp: CPA maxrows, d + BRGE rwsmsout + STA rwxpos, d + LDA maxrows, d + LDX rowssqad, d + CALL rowsum + CPA dgsm, d + STA tmprwsm, d + BREQ rwinccpt + DECO rowid, d + CHARO '\n', i +rwinccpt: LDA rowid, d + ADDA 1, i + STA rowid, d + BR rwsmslp +rwsmsout: RET0 +; Number of rows to compute +maxrows: .BLOCK 2 +; Square address +rowssqad: .BLOCK 2 +; Current rowid +rowid: .BLOCK 2 +; Current rowsum +tmprwsm: .BLOCK 2 + +; Gets an element at the indexes given as parameter +; The square is supposed to contain only integers +; No check will be made on the correctness of the indexes +; +; Parameters: A: Size of a side of the square (in elements) +; X: Base address of the square +; xpos: Position in X for the element (0-indexed) +; ypos: Position in Y for the element (0-indexed) +; +; Return: A will contain the element +; +; Side-effects: Registers A and X will neither be saved nor restored upon call +; ypos will be altered +elemat: STX elsqaddr, d + ASLA + LDX xpos, d + CALL mult + STA xpos, d + LDX ypos, d + ASLX + STX ypos, d + ADDA ypos, d + ADDA elsqaddr, d + STA elsqaddr, d + LDX elsqaddr, d + LDA 0, x + RET0 +; X-index in square (in elements) +xpos: .BLOCK 2 +; Y-index in square (in elements) +ypos: .BLOCK 2 +; Address to fetch elements at +elsqaddr: .BLOCK 2 + +; Fills the square with input from the user +; +; Pass via register A the number of inputs to be read +fillsq: LDX 0, i +filloop: SUBA 1, i + CPA 0, i + BRLT fillout + DECI square, x + ADDX 2, i + BR filloop +fillout: RET0 + +; Computes the sum of the digits of a column +; The square is supposed to contain integers only +; +; Parameters: A: Size of a side of the square +; X: Base address of the square +; cscolid: Identifier of the column (0-based) +; +; Return: A: Sum of the digits of the column +colsum: STA csclsqsz, d + STX csclsqad, d + LDA 0, i + STA csclsum, d + STA csclxpos, d +clsmloop: CPA csclsqsz, d + BRGE colout + LDA cscolid, d + STA ypos, d + LDA csclxpos, d + STA xpos, d + LDA csclsqsz, d + LDX csclsqad, d + CALL elemat + ADDA csclsum, d + STA csclsum, d + LDA csclxpos, d + ADDA 1, i + STA csclxpos, d + BR clsmloop +colout: LDA csclsum, d + RET0 +; Identifier of the column which sum is to be computed +cscolid: .BLOCK 2 +; Temporary for x position +csclxpos: .BLOCK 2 +; Base address of the square +csclsqad: .BLOCK 2 +; Size of a side of the square +csclsqsz: .BLOCK 2 +; Sum of the column +csclsum: .BLOCK 2 + +; Computes the sum of the digits of a row +; The square is supposed to contain integers only +; +; Parameters: A: Size of a side of the square +; X: Base address of the square +; rwxpos: Row index (0-based) +; +; Returns: A: Sum of the digits of the row +rowsum: STA rwsqsz, d + STX rwbsqadr, d + LDA 0,i + STA rwsum, d + STA rwypos, d +rwsumlp: LDA rwypos, d + CPA rwsqsz, d + BRGE rwsumout + STA ypos, d + LDA rwxpos, d + STA xpos, d + LDA rwsqsz, d + LDX rwbsqadr, d + CALL elemat + ADDA rwsum, d + STA rwsum, d + LDA rwypos, d + ADDA 1, i + STA rwypos, d + BR rwsumlp +rwsumout: LDA rwsum, d + RET0 +; Square size (in elements) +rwsqsz: .BLOCK 2 +; Square base address +rwbsqadr: .BLOCK 2 +; Position of the row to compute +rwxpos: .BLOCK 2 +; Current column visited +rwypos: .BLOCK 2 +; Sum of the row +rwsum: .BLOCK 2 + +; Computes the sum for the antidiagonal of a square +; The square is supposed to contain integers only +; +; Parameters: A: Size of a side of the square (elements) +; X: Base address of the square +; +; Returns: A: Sum of the antidiagonal +cdiagsum: STA cdsqsz, d + SUBA 1,i + STA cdtmpy, d + LDA 0, i + STA cdtmpx, d + STA cdsum, d + STX cdsqaddr, d +cdiaglp: LDA cdtmpx, d + STA xpos, d + LDA cdtmpy, d + STA ypos, d + CPA 0, i + BRLT cdout + LDA cdsqsz, d + LDX cdsqaddr, d + CALL elemat + ADDA cdsum, d + STA cdsum,d + LDA cdtmpx, d + ADDA 1, i + STA cdtmpx, d + LDA cdtmpy, d + SUBA 1, i + STA cdtmpy, d + BR cdiaglp +cdout: LDA cdsum, d + RET0 +; Temporary handle for square size (elements) +cdsqsz: .BLOCK 2 +; Square address +cdsqaddr: .BLOCK 2 +; Keep x address +cdtmpx: .BLOCK 2 +; Keep y address +cdtmpy: .BLOCK 2 +; Sum of antidiagonal +cdsum: .BLOCK 2 + +; Computes the sum for the diagonal of a square +; The square is supposed to contain integers only +; +; Parameters: A: Size of a side of the square (elements) +; X: Base address of the square +; +; Returns: A: Sum of the diagonal +; +diagsum: STA dsqsz, d + STX dsqaddr, d + LDA 0, i + STA tmpsum, d + STA curra, d +dglp: CPA dsqsz, d + BRGE dglpout + STA xpos, d + STA ypos, d + LDA dsqsz, d + LDX dsqaddr, d + CALL elemat + ADDA tmpsum, d + STA tmpsum, d + LDA curra, d + ADDA 1, i + STA curra, d + BR dglp +dglpout: LDA tmpsum, d + RET0 +; Address of the square +dsqaddr: .BLOCK 2 +; Size of a side of the square (elements) +dsqsz: .BLOCK 2 +; Current value of the x and y indexes +curra: .BLOCK 2 +; Sum of the values +tmpsum: .BLOCK 2 + +; Muliplies two ints +; +; Parameters: +; Register A : Left part of the multiplication +; Register X : Right part of the multiplication +; +; Return: +; Register A : Result of the multiplication +; +; Side-effects: +; Uses multmp as a temporary value +mult: STA multmp, d + LDA 0, i +muloop: CPX 0, i + BRLE mulout + ADDA multmp, d + SUBX 1, i + BR muloop +mulout: RET0 +; Temporary variable for mult function +; Holds the initial value of A +multmp: .WORD 0 + +; For debugging purposes +; Prints the content of the square to stdout +; +; Parameters: A: Size of a side +; X: Base address of square +; +; Side-effects: +; Consider variables sidesz, sqaddr, sqmaxa as local, they will be written +; Registers A and X will not be saved nor restored upon call +printsq: STA sidesz, d + STX sqaddr, d + LDX sidesz, d + CALL mult + ASLA + ADDA sqaddr, d + STA sqmaxa, d + LDX sqaddr, d + LDA 0, i +priloop: DECO 0, x + CHARO ' ', i + ADDX 2, i + CPX sqmaxa, d + BREQ priout + ADDA 1, i + CPA sidesz, d + BRLT priloop + LDA 0, i + CHARO '\n', i + BR priloop +priout: RET0 +; Size of a side of the square +sidesz: .BLOCK 2 +; Address of the square +sqaddr: .BLOCK 2 +; Maximum address to iterate upon +sqmaxa: .BLOCK 2 + +; ------------------ GLOBALLY ACCESSIBLE SYMBOLS -------------------- ; +; +; Sum of the diagonal for the square +; Reference value for magic-square +dgsm: .WORD 0 +; Sum of the counter-diagonal +cdsm: .WORD 0 +; Input error string +stderr: .ASCII "A number between 1 and 32 (both inclusive) must be entered as value for the size of the square for the program to work.\n\x00" + .END diff --git a/samples/Pep8/qsort.pep b/samples/Pep8/qsort.pep new file mode 100644 index 00000000..ff7d5c71 --- /dev/null +++ b/samples/Pep8/qsort.pep @@ -0,0 +1,227 @@ +; Sorts a statically defined array using the recursive implementation +; of the quicksort algorithm. +; +; In this implementation, the pivot is supposed to be the rightmost +; value of the slice of the array being sorted. +; +; Note that the code presented below should work on any array, +; whether defined statically or dynamically. +; +; Calling conventions: +; Except when mentionned otherwise, every parameter is to be passed on the stack. +; The return values are also on the stack. +; No assumption is to be made on the content of a register on a function call. +; The values of the registers are to be locally saved for further use if necessary. +main: SUBSP 4, i + LDA 11, i + ASLA + STA 2, s + LDA arr, i + STA 0, s + CALL printarr + SUBSP 2, i + LDA arr, i + STA 0, s + LDA 0, i + STA 2, s + LDA 10, i + STA 4, s + CALL qsort + ADDSP 2, i + CHARO '\n', i + LDA 11, i + ASLA + STA 2, s + LDA arr, i + STA 0, s + CALL printarr + STOP + +; Sorts an array using the quicksort algorithm +; +; Parameters: +; - SP + 2: Address of the array +; - SP + 4: Left bound +; - SP + 6: Right bound +; Returns: +; void +qsort: SUBSP 2, i + LDA qsarrlb, s + CPA qsarrrb, s + BRGE qsortout + SUBSP 6, i + LDA 10, s + STA 0, s + LDA 12, s + STA 2, s + LDA 14, s + STA 4, s + CALL part + LDA 10, s + STA 0, s + LDA 12, s + STA 2, s + LDA 6, s + SUBA 1, i + STA 4, s + CALL qsort + LDA 10, s + STA 0, s + LDA 6, s + ADDA 1, i + STA 2, s + LDA 14, s + STA 4, s + CALL qsort + ADDSP 6, i +qsortout: ADDSP 2, i + RET0 +; Address of the array +qsarradd: .EQUATE 4 +; Left bound +qsarrlb: .EQUATE 6 +; Right bound +qsarrrb: .EQUATE 8 +; Pivot value returned by the part command +qsortp: .EQUATE 0 + +; Partitions an array in two following the quicksort rules. +; +; All the lower values compared to the pivot will be on the left +; All the upper values compared to the pivot will be on the right +; The pivot's final index is then returned +; +; Parameters: +; - SP + 2: Address of the array +; - SP + 4: Left bound +; - SP + 6: Right bound +; +; Returns: +; - SP + 8: Pivot final index +part: SUBSP 8, i + LDA parrrb, s + STA partpiv, s + LDA parrlb, s + STA pstind, s + STA piter, s +partflp: CPA parrrb, s + BRGE partout + LDX piter, s + ASLX + LDA paraddr, sxf + STA parrival, s + LDX partpiv, s + ASLX + LDA paraddr, sxf + CPA parrival, s + BRLT parlpinc + SUBSP 6, i ; Call swap(arr, i, st_index) + LDA 16, s + STA 0, s + LDA 8, s + STA 2, s + LDA 10, s + STA 4, s + CALL swap + ADDSP 6, i + LDA pstind, s + ADDA 1, i + STA pstind, s +parlpinc: LDA piter, s + ADDA 1, i + STA piter, s + BR partflp +partout: SUBSP 6, i ; Call swap(arr, piv, st_index) + LDA 16, s + STA 0, s + LDA 12, s + STA 2, s + LDA 10, s + STA 4, s + CALL swap + ADDSP 6, i + LDA pstind, s + ADDSP 8, i + STA 8, s + RET0 +; Address of the array +paraddr: .EQUATE 10 +; Left bound +parrlb: .EQUATE 12 +; Right bound +parrrb: .EQUATE 14 +; Pivot value +partpiv: .EQUATE 6 +; st_index +pstind: .EQUATE 4 +; For iterator value +piter: .EQUATE 2 +; arr[i] value +parrival: .EQUATE 0 + +; Swaps the value of two elements of an array of integers +; +; Parameters: +; - SP + 2: Address of the array +; - SP + 4: Index of the 1st element to swap +; - SP + 6: Index of the 2nd element to swap +; +; Returns: +; void +swap: SUBSP 2, i + LDX fstelind, s + ASLX + LDA arraddr, sxf + STA swaptmp, s + LDX secelind, s + ASLX + LDA arraddr, sxf + LDX fstelind, s + ASLX + STA arraddr, sxf + LDA swaptmp, s + LDX secelind, s + ASLX + STA arraddr, sxf + ADDSP 2, i + RET0 +; Temporary value for the swap +swaptmp: .EQUATE 0 +; Address of the array on which the swap is done +arraddr: .EQUATE 4 +; Index of the first element +fstelind: .EQUATE 6 +; Index of the second element +secelind: .EQUATE 8 + +; Prints the content of an array +; +; Parameters: +; SP + 2: Address of the array +; SP + 4: Length of the array +; +; Returns: +; void +printarr: LDX 0, i +parrlp: CPX 4, s + BRGE parrout + DECO 2, sxf + CHARO ' ', i + ADDX 2, i + BR parrlp +parrout: RET0 + +; Unsorted array for testing purposes +arr: .WORD 9 + .WORD 5 + .WORD 8 + .WORD 10 + .WORD 4 + .WORD 7 + .WORD 0 + .WORD 3 + .WORD 2 + .WORD 1 + .WORD 6 + + .END diff --git a/samples/Pep8/stri_buf.pep b/samples/Pep8/stri_buf.pep new file mode 100644 index 00000000..dcfa1269 --- /dev/null +++ b/samples/Pep8/stri_buf.pep @@ -0,0 +1,61 @@ +main: + +; Reads a string in stdin, returns the buffer it was read in +; Stops reading at the first encounter of a \n character. +; +; Parameters: +; void +; +; Returns: +; - X: Address of the buffer +stri: SUBSP 2, i + LDA 32, i + CALL new + CPX buflen, s + BRGE strinlrg +strinlrg: LDA buflen, d + LDX 2, i + CALL mult + STA buflen + CALL new + +buflen: .EQUATE 0 + +; Copies the content of a buffer to another one +; +; Parameters: +; - SP + 2: Destination buffer +; - SP + 4: Source buffer +; - SP + 6: Length to copy +memcpy: LDX 0, i +memcplp: CPX cpylen, s + BREQ memcpout + LDBYTEA srcbuf, sxf + STBYTEA dstbuf, sxf + ADDX 1, i + BR memcplp +memcpout: RET0 +; Destination buffer +dtsbuf: .EQUATE 2 +; Source buffer +srcbuf: .EQUATE 4 +; Copy length +cpylen: .EQUATE 6 + +; Allocates a new structure in the heap +; +; Parameters: +; - A: Length of the structure to allocate (bytes) +; +; Returns: +; - X: Address of the allocated structure +new: ADDA hpptr, d + LDX hpptr, d + STA hpptr, d + RET0 + +; Pointer to the next available byte on the heap +hpptr: .ADDRSS heap +; Start of the heap +heap: .BLOCK 1 + .END diff --git a/samples/Pep8/stristack.pep b/samples/Pep8/stristack.pep new file mode 100644 index 00000000..93962c8c --- /dev/null +++ b/samples/Pep8/stristack.pep @@ -0,0 +1,50 @@ +main: SUBSP 34, i + LDA 31, i + STA 0, s + CALL fgets + ADDSP 2, i + CALL ststro + STOP + +; Reads a string from stdin, stops reading when one of the following is true: +; - Read a \n +; - Read a maximum of `max` chars +; +; Parameters: +; - SP + 2: `max`, the maximum number of chars to read +; - SP + 4: `buffer` of length `max` + 1 +; Returns: +; void +fgets: LDX 0, i + LDA 0, i +fgetslp: CHARI buffer, sx + LDBYTEA buffer, sx + CPA '\n', i + BREQ fout + CPX max, s + BREQ fout + ADDX 1, i + BR fgetslp +fout: LDA '\x00', i + STBYTEA buffer, sx + RET0 +max: .EQUATE 2 +buffer: .EQUATE 4 + +; Prints a string stored in stack +; +; Parameters: +; SP + 2: `string` +; Returns: +; void +ststro: LDX 0, i + LDA 0, i +strolp: LDBYTEA string, sx + CPA '\x00', i + BREQ strout + CHARO string, sx + ADDX 1, i + BR strolp +strout: RET0 +string: .EQUATE 2 + .END diff --git a/vendor/grammars/Sublime-Pep8 b/vendor/grammars/Sublime-Pep8 new file mode 160000 index 00000000..be653c63 --- /dev/null +++ b/vendor/grammars/Sublime-Pep8 @@ -0,0 +1 @@ +Subproject commit be653c638b2b042c90384f5d3f335d93172bcd85 diff --git a/vendor/licenses/grammar/Sublime-Pep8.txt b/vendor/licenses/grammar/Sublime-Pep8.txt new file mode 100644 index 00000000..a81695b7 --- /dev/null +++ b/vendor/licenses/grammar/Sublime-Pep8.txt @@ -0,0 +1,18 @@ +--- +type: grammar +name: Sublime-Pep8 +license: wtfpl +--- + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO.