Add Pep8 Assembly language (#2070)

Pep/8 is a toy assembly language used in some universities for teaching
the basics of assembly and low-level programming.

Signed-off-by: Lucas Bajolet <lucas.bajolet@gmail.com>
This commit is contained in:
Lucas Bajolet
2017-05-15 04:02:06 -04:00
committed by Colin Seymour
parent acbab53198
commit ded651159d
12 changed files with 1536 additions and 0 deletions

3
.gitmodules vendored
View File

@@ -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

View File

@@ -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:

View File

@@ -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

34
samples/Pep8/div.pep Normal file
View File

@@ -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

23
samples/Pep8/flag.pep Normal file
View File

@@ -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

675
samples/Pep8/linked.pep Normal file
View File

@@ -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

434
samples/Pep8/msq.pep Normal file
View File

@@ -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

227
samples/Pep8/qsort.pep Normal file
View File

@@ -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

61
samples/Pep8/stri_buf.pep Normal file
View File

@@ -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

View File

@@ -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

1
vendor/grammars/Sublime-Pep8 vendored Submodule

View File

@@ -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 <sam@hocevar.net>
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.