; =================== source-file: _lastmember.asm =====================
;
; Purpose: Returns the last element of a list; if the list is empty, it
; returns the empty list-element. The list can be of any type / domain,
; including real numbers (for which there is a second variant, since real
; number lists in Visual Prolog have 16-byte elements, instead of 12-byte
; elements.
IDEAL
P586
MODEL flat
CODESEG
ALIGN 4
public _lastmember_0
public _lastmember_1
PROC _lastmember_0 near
mov ecx,[esp+4] ; input-list.....................ARG-1(i)
mov edx,ecx ; initialize EDX as last_element pointer
mov ah,2 ; prepare AH = 2 (end-element flag)
push ebx ; preserve EBX
mov ebx,8 ;
@@p1:
mov al,[byte ptr ecx] ; put the "element-type indicator" in AL
cmp al,ah ; compare with 2 (end-of-list indicator)
jz @@xx ; if end of list, then exit!
; ---------------------------
mov edx,ecx ; else, store the current list_pointer
mov ecx,[ecx+ebx] ; make ECX = next list-element-pointer
jmp short @@p1 ; repeat the loop
; ===========================
@@xx: shr ebx,1 ; make ebx = 4
mov eax,[edx+ebx] ;
pop ebx ; restore EBX
retn
ENDP _lastmember_0
PROC _lastmember_1 near ; for REAL-lists, only!
mov ecx,[esp+4] ; input-list.....................ARG-1(i)
mov edx,ecx ; initialize EDX as last_element pointer
mov ah,2 ; prepare AH = 2 (end-element flag)
push ebx ; preserve EBX
mov ebx,12 ; REAL numbers require 12-byte jumps
@@p1:
mov al,[byte ptr ecx] ; put the "element-type indicator" in AL
cmp al,ah ; compare with 2 (end-of-list indicator)
jz @@xx ; if end of list, then exit!
; ---------------------------
mov edx,ecx ; else, store the current list_pointer
mov ecx,[ecx+ebx] ; make ECX = next list-element-pointer
jmp short @@p1 ; repeat the loop
; ===========================
@@xx:
fld [qword ptr edx+4] ; return the real number in address [edx+4]
pop ebx ; restore EBX
retn
ENDP _lastmember_1
end
; ================= VISUAL PROLOG TEST-PROGRAM: ==================
GLOBAL DOMAINS
ILIST = INTEGER*
RLIST = REAL*
SLIST = STRING*
GLOBAL PREDICATES
INTEGER lastmember(ILIST) -(i) language c %_lastmember_0
REAL lastmember(RLIST) -(i) language c %_lastmember_1
STRING lastmember(SLIST) -(i) language c as "_lastmember_0"
% PNT lastmember(PNTLIST) -(i) language c as "_lastmember_0" (etc.)
GOAL
List2 = [22,33,44,55,66,77], LastINT = lastmember(List2),
write("\nfor an integer-list: ",List2,", LastINT = ",LastINT), nl,
List1 = ["this","that","ok","fourth","end"], LastSTR = lastmember(List1),
write("\nfor a string-list: ",List1,", LastSTR = \"",LastSTR,"\"\n"),
List3 = [2.1,2.3,4.1,5.67], LastREAL = lastmember(List3),
write("\nfor a Real-list: ",List3,", LastREAL = ",LastREAL), nl,
readchar(CHx), CHx = '\27', !.
; ************** "32-bit Assembly Language Extensions for Visual Prolog" ****************
; Written by George A. Stathis (c) 2005, E-mail: omadeon@yahoo.com, gstathis@enm.gr
; URL: http://www.omadeon.com/asm Company: ENB Ltd. Company site: http://www.enb.gr
; **** Use of this source-code is unrestricted provided that the author is mentioned. ****