diff --git a/04_semantics_and_running/main.py b/04_semantics_and_running/main.py index 3318b47..02e9620 100644 --- a/04_semantics_and_running/main.py +++ b/04_semantics_and_running/main.py @@ -305,7 +305,7 @@ class CompileData: subq $16, %rsp movq %rdi, 0(%rsp) leaq 0(%rsp), %rdi - call gmtime + call localtime movq $date_buffer, %rdi movq $(date_buffer_end - date_buffer), %rsi movq $date_format, %rdx @@ -318,6 +318,25 @@ class CompileData: ret ''' + self.callables['__builtin_get_day_attr'] = '''\ + pushq %rbp + movq %rsp, %rbp + subq $16, %rsp + movq %rdi, 0(%rsp) + movq %rsi, 8(%rsp) + leaq 0(%rsp), %rdi + call localtime + movq $date_buffer, %rdi + movq $(date_buffer_end - date_buffer), %rsi + movq 8(%rsp), %rdx + movq %rax, %rcx + call strftime + movq $date_buffer, %rdi + call atoi + leave + ret + ''' + def get_label(self) -> str: self.label_counter += 1 return f'.L{self.label_counter - 1}' @@ -353,6 +372,11 @@ class CompileData: prefix += 'int_format: .asciz "%lld"\n' prefix += 'str_format: .asciz "%s"\n' prefix += 'date_format: .asciz "%Y-%m-%d"\n' + prefix += 'day_format: .asciz "%d"\n' + prefix += 'month_format: .asciz "%m"\n' + prefix += 'year_format: .asciz "%Y"\n' + prefix += 'weekday_format: .asciz "%u"\n' + prefix += 'weeknum_format: .asciz "%W"\n' for index, string in enumerate(self.string_literals): prefix += f'S{index}: .asciz "{string}"\n' prefix += '\n' @@ -546,6 +570,11 @@ def compile_ast(node: ASTnode, compile_data: CompileData) -> None: compile_data.code += f' movq ${label}, %rax\n' case 'date_literal': compile_data.code += f' movq ${timegm(node.value.timetuple())}, %rax\n' + case 'attribute_read': + compile_ast(node.child_identifier, compile_data) + compile_data.code += f' movq %rax, %rdi\n' + compile_data.code += f' movq ${node.child_attribute.value}_format, %rsi\n' + compile_data.code += f' call __builtin_get_day_attr\n' case 'do_until': label_loop = compile_data.get_label() compile_data.insert_label(label_loop)