Page 1 of 1

Anonymous functions

Posted: Sun Jan 02, 2022 6:07 pm
by frank
SharpBASIC supports anonymous functions, i.e. functions that do not need an identifier. This is particularly useful for isolating small, unique pieces of code. Anonymous functions have their own scope and cannot see identifiers directly outside their scope. However, identifiers can optionally be passed as parameters. Anonymous functions are defined and called with the keyword afunc:

Code: Select all

a = afunc()
do
end;
Example:

Code: Select all

dim a, n: int;

main do
  n = 7;
  a = afunc(n)
    dim r: int = 0;
    dim i: itr;
  do
    for i = 1 to n :++ do
      r = r + i;
    end;
    return r;
  end;
  print(a);   ' 28
end;
The generated raw assembly code (without any optimization) shows the stack frame without call (no address on the stack):

Code: Select all

_start:
; load immediate constant '7'
	movsx   eax, byte [_C4]
; save n
	mov     [_I76], eax
; load n
	mov     eax, dword [_I76]
	push    eax
	push    ebp
	mov     ebp, esp
	sub     esp, 12
; init afunc
	mov     dword [ebp - 4], 0
; load immediate constant '0'
	movsx   eax, byte [_C5]
; save r
	mov     [ebp - 12], eax
; load immediate constant '1'
	movsx   eax, byte [_C6]
; save i
	mov     [ebp - 8], eax
; dec i
	dec     dword [ebp - 8]
; load n
	mov     eax, dword [ebp + 4]
	push    eax
._L1:
; inc i
	inc     dword [ebp - 8]
	pop     eax
; cmp i
	cmp     [ebp - 8], eax
	jg      ._L2
	push    eax
; load r
	mov     eax, dword [ebp - 12]
	push    eax
; load i
	mov     eax, dword [ebp - 8]
	pop     edx
	add     eax, edx
; save r
	mov     [ebp - 12], eax
	jmp     ._L1
._L2:
; load r
	mov     eax, dword [ebp - 12]
; save afunc result
	mov     [ebp - 4], eax
	jmp     ._L0
._L0:
; load afunc result
	mov     eax, dword [ebp - 4]
	mov     esp, ebp
	pop     ebp
	add     esp, 4

; save a
	mov     [_I75], eax
; print:
; load a
	mov     eax, dword [_I75]
	call    _sb_print_int

_end:
	mov     ebx, 0
	mov     eax, 1
	int     80h