2026-07-10 10:38:57 +02:00

144 lines
3.7 KiB
Python

import random
import time
from ScEpTIC.AST.builtins.builtin import Builtin
from ScEpTIC.AST.elements.value import Value
"""
some stdio.h library functions
"""
class debug_print(Builtin):
"""
Definition of the debug_print() builtin
Note: you can use debug_print() inside your code and will print all the arguments that it receives.
"""
def get_val(self):
print('[Debug Print]: {}'.format(self.args))
return 0
class memcmp(Builtin):
"""
Definition of the memcmp() builtin
"""
def get_val(self):
buffer_1_addr = self.args[0]
buffer_2_addr = self.args[1]
# element number of i8 -> bytes
buffer_length = self.args[2]
buffer_1 = self._vmstate.memory.get_cells_from_address(buffer_1_addr, buffer_length, False)
self._vmstate.memory.simulate_mmu_read_on_cells(buffer_1)
buffer_2 = self._vmstate.memory.get_cells_from_address(buffer_2_addr, buffer_length, False)
self._vmstate.memory.simulate_mmu_read_on_cells(buffer_2)
for i in range(0, len(buffer_1)):
val_1 = buffer_1[i].content
if isinstance(val_1, str):
val_1 = ord(val_1)
val_2 = buffer_2[i].content
if isinstance(val_2, str):
val_2 = ord(val_2)
# compensate for memory representation
if val_1 < 0:
val_1 = Value.convert_sint_to_uint(val_1, buffer_1[i].dimension*8)
if val_2 < 0:
val_2 = Value.convert_sint_to_uint(val_2, buffer_2[i].dimension*8)
if val_1 != val_2:
return val_1 - val_2
return 0
class randombuiltin(Builtin):
"""
Definition of the rand() builtin
"""
def get_val(self):
RAND_MAX = 32767
return random.randint(0, RAND_MAX)
class srandombuiltin(Builtin):
"""
Definition of the srand() builtin
"""
def get_val(self):
random.seed(int(self.args[0]))
class exitbuiltin(Builtin):
"""
Definition of the exit() builtin
"""
def get_val(self):
# set program to its end
self._vmstate.register_file.pc.update(self._vmstate.main_function_name, self._vmstate.main_function_len)
# set main return value to the one passed to exit
self._vmstate.main_return_value = self.args[0]
class timebuiltin(Builtin):
"""
Definiton of the time() builtin
"""
def get_val(self):
return int(time.time())
class strlen(Builtin):
"""
Definition of the strlen() builtin
"""
def get_val(self):
base_addr = self.args[0]
str_len = 0
bits = 8
while True:
addr = self._vmstate.memory.add_offset(base_addr, bits*str_len)
data = self._vmstate.memory.get_cells_from_address(addr, bits)
self._vmstate.memory.simulate_mmu_read_on_cells(data)
if len(data) != 1:
raise Exception("strlen() error: multiple cells within 8 bits!")
if data[0].content == 0:
break
str_len += 1
return str_len
# custom print
debug_print.define_builtin('debug_print', 'i32', 'void')
# definition for memcmp() and strncmp()
memcmp.define_builtin('memcmp', 'i8, i8, i64', 'i32')
memcmp.define_builtin('strncmp', 'i8, i8, i64', 'i32')
# random functions
randombuiltin.define_builtin('rand', '', 'i32')
srandombuiltin.define_builtin('srand', 'i32', 'void')
# definition for exit()
exitbuiltin.define_builtin('exit', 'i32', 'void')
strlen.define_builtin('strlen', 'i8', 'i64')
timebuiltin.define_builtin('time', '', 'i32')