Skip to content

Ymit24/GLang

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 

Repository files navigation

GLang

A programming language implementation for fun.

Here is some example code

This code uses the most cutting edge feature set of the language. In some cases there is a known bug where one byte isn't returned properly, this is likely a stack misalignment error which I never got around to fixing.

// You can include standard libc functions
extern printf
extern memcpy

// This function returns an array of 13 bytes
#gen_arr:->u8(13):
 // Declare an array of 13 bytes with uninitialized data
 buf : u8(13) = _
 // Typical C style three section for loop
 for (i : i32 = 0, i < 13, i++):
  // This uses some pointer arithmetic to assign values to the bytes in the array
  $(@buf + i) = i
 end
 // return the buffer from the function
 ret buf 

// This function takes two arrays of 13 bytes each and prints them
#printarr:(arr: u8(13)),(arr2:u8(13)):
 for (i : i32 = 0, i < 13, i++):
  // Call the standard printf using all the normal format specifiers.
  // Use some pointer arithmetic to get the values from the byte arrays
  [printf "arr %d => %d :: %d\n", i, $(@arr+i), $(@arr2 + i)]
 end
 // Print out the memory address differences as an example
 [printf "address difference: %d\n", (@arr2 - @arr)]
 ret

// This is the typical C equivalent main function.
#main:
 // Call the printarr function passing in the return value of gen_arr for each argument.
 // The compiler handles moving all the memory around for us!
 [printarr [gen_arr], [gen_arr]]
 ret

Here is the NASM generated code

This then can be converted into executable machine code using the nasm tool. NOTE: The comments are auto generated by the compiler based on the source code.

BITS 32
global main
extern memcpy ; Make sure we always have this
extern printf
extern memcpy
section .data
__str0: db 'arr %d => %d :: %d', 0xA, 0
__str1: db 'address difference: %d', 0xA, 0
section .text

;function declaration gen_arr
gen_arr:
push ebp
mov ebp, esp
sub esp, 16

;variable i=0
push DWORD 0 ; Push 0
pop eax
mov [ebp-20], eax
sub esp, 4 ; make room for scope variables
.__for_0:
; loop condition
push DWORD [ebp-20] ; Push i value
push DWORD 13 ; Push 13
; LSS expression
pop edx
pop eax
cmp eax,edx
setl al
push eax
pop eax
 ; eax now has result of condition (either 0 or 1)
cmp eax, 0
 ; check if condition was true or false
je .__forend_natural_0
; for body
;variable defref expr
push DWORD [ebp-20] ; Push i value
lea eax, [ebp-16]; Get address of buf
push eax; push address onto stack
push DWORD [ebp-20] ; Push i value
pop edx ; Get Right
pop eax ; Get left
add eax, edx; Add
push eax ; Push result
pop edx ; Load address
pop eax ; Load value
mov [edx], al ; type sensitive write
; incrementor
.__forinc_0:
inc DWORD [ebp-20] ; Increment i
; jump to start of loop
jmp .__for_0
.__forend_natural_0:
add esp, 4 ; pop natural for scope
.__forend_0:
; copy array onto stack
sub esp, 16
mov edx, esp
push 16
lea eax, [ebp-16]
push eax
push edx
call memcpy
add esp, 12
mov edx, esp ; Compute stack address
push 16 ; Push size
push edx; Push src*
lea edx, [ebp+8] ; Compute address of return space
push edx ; Push dst*
call memcpy
add esp, 12
add esp, 16 ; clean up special stack
mov eax, edx ; Move address of special stack into eax

;return
mov esp, ebp
pop ebp
ret

;end function gen_arr

;function declaration printarr2
printarr2:
push ebp
mov ebp, esp
sub esp, 0

;variable i=0
push DWORD 0 ; Push 0
pop eax
mov [ebp-4], eax
sub esp, 4 ; make room for scope variables
.__for_1:
; loop condition
push DWORD [ebp-4] ; Push i value
push DWORD 13 ; Push 13
; LSS expression
pop edx
pop eax
cmp eax,edx
setl al
push eax
pop eax
 ; eax now has result of condition (either 0 or 1)
cmp eax, 0
 ; check if condition was true or false
je .__forend_natural_1
; for body
lea eax, [ebp+20]; Get address of arr2
push eax; push address onto stack
push DWORD [ebp-4] ; Push i value
pop edx ; Get Right
pop eax ; Get left
add eax, edx; Add
push eax ; Push result
pop eax ; Load address
movzx eax, BYTE [eax] ; Type sensitive Read
push eax ; Push Value
lea eax, [ebp+4]; Get address of arr
push eax; push address onto stack
push DWORD [ebp-4] ; Push i value
pop edx ; Get Right
pop eax ; Get left
add eax, edx; Add
push eax ; Push result
pop eax ; Load address
movzx eax, BYTE [eax] ; Type sensitive Read
push eax ; Push Value
push DWORD [ebp-4] ; Push i value
push __str0
call printf
add esp, 16
; incrementor
.__forinc_1:
inc DWORD [ebp-4] ; Increment i
; jump to start of loop
jmp .__for_1
.__forend_natural_1:
add esp, 4 ; pop natural for scope
.__forend_1:
lea eax, [ebp+20]; Get address of arr2
push eax; push address onto stack
lea eax, [ebp+4]; Get address of arr
push eax; push address onto stack
pop edx ; Get Right
pop eax ; Get Left
sub eax, edx ; Subtract
push eax ; Push result
push __str1
call printf
add esp, 8

;return
mov esp, ebp
pop ebp
ret

;end function printarr2

;function declaration main
main:
push ebp
mov ebp, esp
sub esp, 0
sub esp, 16 ; Push space for return type
push esp ; push return space pointer as hidden first parameter
call gen_arr
add esp, 4
sub esp, 16 ; Push space for return type
push esp ; push return space pointer as hidden first parameter
call gen_arr
add esp, 4
call printarr2
add esp, 8

;return
mov esp, ebp
pop ebp
ret

;end function main

About

A programming language implementation for fun.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors