We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
-------------------- [ERROR] An uncaught error has occurred! Here are the details that may help solve this issue. Error: `SimulatorError: The heap has grown into the stack. ID: 'step'! ` Data: {"venus":"true","trace_format":"%output%%0%\t%1%\t%2%\t%3%\t%4%\t%5%\t%6%\t%7%\t%8%\t%9%\t%10%\t%11%\t%12%\t%13%\t%14%\t%15%\t%16%\t%17%\t%18%\t%19%\t%20%\t%21%\t%22%\t%23%\t%24%\t%25%\t%26%\t%27%\t%28%\t%29%\t%30%\t%31%\t%line%\t%pc%\t%inst%\n","trace_base":"2","trace_totCommands":"-1","trace_maxSteps":"-1","trace_instFirst":"false","trace_wordAddressed":"false","trace_TwoStage":"false","history_limit":"-1","text_begin":"0","aligned_memory":"false","mutable_text":"true","ecall_exit_only":"false","set_regs_on_init":"true","simargs":"","enableCallingConvention":"false","prog":"# Compiled ChocoPy Program to RISC-V assembly\n# Execute (run or step-through) using the 'Simulator' tab above \n# Output will appear on the bottom-left of the simulator\n .equiv @sbrk, 9\n .equiv @print_string, 4\n .equiv @print_char, 11\n .equiv @print_int, 1\n .equiv @exit2, 17\n .equiv @read_string, 8\n .equiv @fill_line_buffer, 18\n .equiv @.__obj_size__, 4\n .equiv @.__len__, 12\n .equiv @.__int__, 12\n .equiv @.__bool__, 12\n .equiv @.__str__, 16\n .equiv @.__elts__, 16\n .equiv @error_div_zero, 2\n .equiv @error_arg, 1\n .equiv @error_oob, 3\n .equiv @error_none, 4\n .equiv @error_oom, 5\n .equiv @error_nyi, 6\n .equiv @listHeaderWords, 4\n .equiv @strHeaderWords, 4\n .equiv @bool.True, const_1\n .equiv @bool.False, const_0\n\n.data\n\n.globl $object$prototype\n$object$prototype:\n .word 0 # Type tag for class: object\n .word 3 # Object size\n .word $object$dispatchTable # Pointer to dispatch table\n .align 2\n\n.globl $int$prototype\n$int$prototype:\n .word 1 # Type tag for class: int\n .word 4 # Object size\n .word $int$dispatchTable # Pointer to dispatch table\n .word 0 # Initial value of attribute: __int__\n .align 2\n\n.globl $bool$prototype\n$bool$prototype:\n .word 2 # Type tag for class: bool\n .word 4 # Object size\n .word $bool$dispatchTable # Pointer to dispatch table\n .word 0 # Initial value of attribute: __bool__\n .align 2\n\n.globl $str$prototype\n$str$prototype:\n .word 3 # Type tag for class: str\n .word 5 # Object size\n .word $str$dispatchTable # Pointer to dispatch table\n .word 0 # Initial value of attribute: __len__\n .word 0 # Initial value of attribute: __str__\n .align 2\n\n.globl $.list$prototype\n$.list$prototype:\n .word -1 # Type tag for class: .list\n .word 4 # Object size\n .word 0 # Pointer to dispatch table\n .word 0 # Initial value of attribute: __len__\n .align 2\n\n.globl $object$dispatchTable\n$object$dispatchTable:\n .word $object.__init__ # Implementation for method: object.__init__\n\n.globl $int$dispatchTable\n$int$dispatchTable:\n .word $object.__init__ # Implementation for method: int.__init__\n\n.globl $bool$dispatchTable\n$bool$dispatchTable:\n .word $object.__init__ # Implementation for method: bool.__init__\n\n.globl $str$dispatchTable\n$str$dispatchTable:\n .word $object.__init__ # Implementation for method: str.__init__\n\n.text\n\n.globl main\nmain:\n lui a0, 8192 # Initialize heap size (in multiples of 4KB)\n add s11, s11, a0 # Save heap size\n jal heap.init # Call heap.init routine\n mv gp, a0 # Initialize heap pointer\n mv s10, gp # Set beginning of heap\n add s11, s10, s11 # Set end of heap (= start of heap + heap size)\n mv ra, zero # No normal return from main program.\n mv fp, zero # No preceding frame.\n mv fp, zero # Top saved FP is 0.\n mv ra, zero # No function return from top level.\n addi sp, sp, [email protected] # Reserve space for stack frame.\n sw ra, @..main.size-4(sp) # return address\n sw fp, @..main.size-8(sp) # control link\n addi fp, sp, @..main.size # New fp is at old SP.\n jal initchars # Initialize one-character strings.\n li a0, 4 # Load integer literal 4\n sw a0, -28(fp) # Push argument 5 from last.\n li a0, 8 # Load integer literal 8\n sw a0, -32(fp) # Push argument 4 from last.\n li a0, 15 # Load integer literal 15\n sw a0, -36(fp) # Push argument 3 from last.\n li a0, 16 # Load integer literal 16\n sw a0, -40(fp) # Push argument 2 from last.\n li a0, 23 # Load integer literal 23\n sw a0, -44(fp) # Push argument 1 from last.\n li a0, 5 # Pass list length\n sw a0, -48(fp) # Push argument 0 from last.\n addi sp, fp, -48 # Set SP to last argument.\n jal conslist # Move values to new list object\n addi sp, fp, [email protected] # Set SP to stack frame top.\n sw a0, -12(fp) # Push argument 1 from last.\n li a0, 15 # Load integer literal 15\n sw a0, -16(fp) # Push argument 0 from last.\n addi sp, fp, -16 # Set SP to last argument.\n jal $contains # Invoke function: contains\n addi sp, fp, [email protected] # Set SP to stack frame top.\n beqz a0, label_2 # Branch on false.\n la a0, const_2 # Load string literal\n sw a0, -16(fp) # Push argument 0 from last.\n addi sp, fp, -16 # Set SP to last argument.\n jal $print # Invoke function: print\n addi sp, fp, [email protected] # Set SP to stack frame top.\n j label_1 # Then body complete; jump to end-if\nlabel_2: # Else body\n la a0, const_3 # Load string literal\n sw a0, -16(fp) # Push argument 0 from last.\n addi sp, fp, -16 # Set SP to last argument.\n jal $print # Invoke function: print\n addi sp, fp, [email protected] # Set SP to stack frame top.\nlabel_1: # End of if-else statement\n .equiv @..main.size, 48\nlabel_0: # End of program\n li a0, 10 # Code for ecall: exit\n ecall\n\n.globl $object.__init__\n$object.__init__:\n# Init method for type object.\t\n mv a0, zero # `None` constant\n jr ra # Return\n\n.globl $print\n$print:\n# Function print\n lw a0, 0(sp) # Load arg\n beq a0, zero, print_6 # None is an illegal argument\n lw t0, 0(a0) # Get type tag of arg\n li t1, 1 # Load type tag of `int`\n beq t0, t1, print_7 # Go to print(int)\n li t1, 3 # Load type tag of `str`\n beq t0, t1, print_8 # Go to print(str)\n li t1, 2 # Load type tag of `bool`\n beq t0, t1, print_9 # Go to print(bool)\nprint_6: # Invalid argument\n li a0, 1 # Exit code for: Invalid argument\n la a1, const_4 # Load error message as str\n addi a1, a1, @.__str__ # Load address of attribute __str__\n j abort # Abort\n\n# Printing bools\nprint_9: # Print bool object in A0\n lw a0, @.__bool__(a0) # Load attribute __bool__\n beq a0, zero, print_10 # Go to: print(False)\n la a0, const_5 # String representation: True\n j print_8 # Go to: print(str)\nprint_10: # Print False object in A0\n la a0, const_6 # String representation: False\n j print_8 # Go to: print(str)\n\n# Printing strs.\nprint_8: # Print str object in A0\n addi a1, a0, @.__str__ # Load address of attribute __str__\n j print_11 # Print the null-terminated string is now in A1\n mv a0, zero # Load None\n j print_5 # Go to return\nprint_11: # Print null-terminated string in A1\n li a0, @print_string # Code for ecall: print_string\n ecall # Print string\n li a1, 10 # Load newline character\n li a0, @print_char # Code for ecall: print_char\n ecall # Print character\n j print_5 # Go to return\n\n# Printing ints.\nprint_7: # Print int object in A0\n lw a1, @.__int__(a0) # Load attribute __int__\n li a0, @print_int # Code for ecall: print_int\n ecall # Print integer\n li a1, 10 # Load newline character\n li a0, 11 # Code for ecall: print_char\n ecall # Print character\n\nprint_5: # End of function\n mv a0, zero # Load None\n jr ra # Return to caller\n\n.globl $len\n$len:\n# Function len\n # We do not save/restore fp/ra for this function\n # because we know that it does not use the stack or does not\n # call other functions.\n\n lw a0, 0(sp) # Load arg\n beq a0, zero, len_12 # None is an illegal argument\n lw t0, 0(a0) # Get type tag of arg\n li t1, 3 # Load type tag of `str`\n beq t0, t1, len_13 # Go to len(str)\n li t1, -1 # Load type tag for list objects\n beq t0, t1, len_13 # Go to len(list)\nlen_12: # Invalid argument\n li a0, @error_arg # Exit code for: Invalid argument\n la a1, const_4 # Load error message as str\n addi a1, a1, @.__str__ # Load address of attribute __str__\n j abort # Abort\nlen_13: # Get length of string\n lw a0, @.__len__(a0) # Load attribute: __len__\n jr ra # Return to caller\n\n.globl $input\n$input:\n\n addi sp, sp, -16\n sw ra, 12(sp)\n sw fp, 8(sp)\n sw s1, 4(sp)\n addi fp, sp, 16\n li a0, @fill_line_buffer\n ecall\n bgez a0, input_nonempty\n la a0, $str$prototype\n j input_done\ninput_nonempty:\n mv s1, a0\n addi t0, s1, 5\n addi t0, t0, @.__str__\n srli a1, t0, 2\n la a0, $str$prototype\n jal ra, alloc2\n sw s1, @.__len__(a0)\n mv a2, s1\n mv s1, a0\n addi a1, a0, @.__str__\n li a0, @read_string\n ecall\n addi a0, a0, 1\n sw a0, @.__len__(s1)\n add t0, a0, s1\n li t1, 10\n sb t1, @.__str__-1(t0)\n sb zero, @.__str__(t0)\n mv a0, s1\ninput_done:\n lw s1, -12(fp)\n lw ra, -4(fp)\n lw fp, -8(fp)\n addi sp, sp, 16\n jr ra\n\n.globl $contains\n$contains:\n addi sp, sp, [email protected] # Reserve space for stack frame.\n sw ra, @contains.size-4(sp) # return address\n sw fp, @contains.size-8(sp) # control link\n addi fp, sp, @contains.size # New fp is at old SP.\n li a0, 0 # Load integer literal 0\n sw a0, -12(fp) # local variable i\n j label_6 # Jump to loop test\nlabel_5: # Top of while loop\n lw a0, 4(fp) # Load var: contains.items\n sw a0, -16(fp) # Push on stack slot 4\n lw a0, -12(fp) # Load var: contains.i\n lw a1, -16(fp) # Pop stack slot 4\n bnez a1, label_8 # Ensure not None\n j error.None # Go to error handler\nlabel_8: # Not None\n lw t0, 12(a1) # Load attribute: __len__\n bltu a0, t0, label_9 # Ensure 0 <= index < len\n j error.OOB # Go to error handler\nlabel_9: # Index within bounds\n addi a0, a0, 4 # Compute list element offset in words\n li t0, 4 # Word size in bytes\n mul a0, a0, t0 # Compute list element offset in bytes\n add a0, a1, a0 # Pointer to list element\n lw a0, 0(a0) # Get list element\n sw a0, -16(fp) # Push on stack slot 4\n lw a0, 0(fp) # Load var: contains.x\n lw t0, -16(fp) # Pop stack slot 4\n bne t0, a0, label_7 # Branch on not ==\n li a0, 1 # Load boolean literal: true\n j label_4 # Go to return\nlabel_7: # End of if-else statement\n lw a0, -12(fp) # Load var: contains.i\n sw a0, -16(fp) # Push on stack slot 4\n li a0, 1 # Load integer literal 1\n lw t0, -16(fp) # Pop stack slot 4\n add a0, t0, a0 # Operator +\n sw a0, -12(fp) # Assign var: contains.i\nlabel_6: # Test loop condition\n lw a0, -12(fp) # Load var: contains.i\n sw a0, -16(fp) # Push on stack slot 4\n lw a0, 4(fp) # Load var: contains.items\n sw a0, -32(fp) # Push argument 0 from last.\n addi sp, fp, -32 # Set SP to last argument.\n jal $len # Invoke function: len\n addi sp, fp, [email protected] # Set SP to stack frame top.\n lw t0, -16(fp) # Pop stack slot 4\n blt t0, a0, label_5 # Branch on <\n li a0, 0 # Load boolean literal: false\n j label_4 # Go to return\n mv a0, zero # Load None\n j label_4 # Jump to function epilogue\nlabel_4: # Epilogue\n .equiv @contains.size, 32\n lw ra, -4(fp) # Get return address\n lw fp, -8(fp) # Use control link to restore caller's fp\n addi sp, sp, @contains.size # Restore stack pointer\n jr ra # Return to caller\n\n.globl alloc\nalloc:\n# Runtime support function alloc.\n # Prototype address is in a0.\n lw a1, 4(a0) # Get size of object in words\n j alloc2 # Allocate object with exact size\n\n.globl alloc2\nalloc2:\n# Runtime support function alloc2 (realloc).\n # Prototype address is in a0.\n # Number of words to allocate is in a1.\n li a2, 4 # Word size in bytes\n mul a2, a1, a2 # Calculate number of bytes to allocate\n add a2, gp, a2 # Estimate where GP will move\n bgeu a2, s11, alloc2_15 # Go to OOM handler if too large\n lw t0, @.__obj_size__(a0) # Get size of object in words\n mv t2, a0 # Initialize src ptr\n mv t3, gp # Initialize dest ptr\nalloc2_16: # Copy-loop header\n lw t1, 0(t2) # Load next word from src\n sw t1, 0(t3) # Store next word to dest\n addi t2, t2, 4 # Increment src\n addi t3, t3, 4 # Increment dest\n addi t0, t0, -1 # Decrement counter\n bne t0, zero, alloc2_16 # Loop if more words left to copy\n mv a0, gp # Save new object's address to return\n sw a1, @.__obj_size__(a0) # Set size of new object in words\n # (same as requested size)\n mv gp, a2 # Set next free slot in the heap\n jr ra # Return to caller\nalloc2_15: # OOM handler\n li a0, @error_oom # Exit code for: Out of memory\n la a1, const_7 # Load error message as str\n addi a1, a1, @.__str__ # Load address of attribute __str__\n j abort # Abort\n\n.globl abort\nabort:\n# Runtime support function abort (does not return).\n mv t0, a0 # Save exit code in temp\n li a0, @print_string # Code for print_string ecall\n ecall # Print error message in a1\n li a1, 10 # Load newline character\n li a0, @print_char # Code for print_char ecall\n ecall # Print newline\n mv a1, t0 # Move exit code to a1\n li a0, @exit2 # Code for exit2 ecall\n ecall # Exit with code\nabort_17: # Infinite loop\n j abort_17 # Prevent fallthrough\n\n.globl heap.init\nheap.init:\n# Runtime support function heap.init.\n mv a1, a0 # Move requested size to A1\n li a0, @sbrk # Code for ecall: sbrk\n ecall # Request A1 bytes\n jr ra # Return to caller\n\n.globl concat\nconcat:\n\n addi sp, sp, -32\n sw ra, 28(sp)\n sw fp, 24(sp)\n addi fp, sp, 32\n\tsw s1, -12(fp)\n sw s2, -16(fp)\n sw s3, -20(fp)\n\tsw s4, -24(fp)\n sw s5, -28(fp)\n lw t0, 4(fp)\n lw t1, 0(fp)\n beqz t0, concat_none\n beqz t1, concat_none\n lw t0, @.__len__(t0)\n lw t1, @.__len__(t1)\n add s5, t0, t1\n addi a1, s5, @listHeaderWords\n la a0, $.list$prototype\n jal alloc2\n sw s5, @.__len__(a0)\n\tmv s5, a0\n addi s3, s5, @.__elts__\n lw s1, 4(fp)\n\tlw s2, @.__len__(s1)\n addi s1, s1, @.__elts__\n\tlw s4, 12(fp)\nconcat_1:\n beqz s2, concat_2\n lw a0, 0(s1)\n\tjalr ra, s4, 0\n sw a0, 0(s3)\n addi s2, s2, -1\n addi s1, s1, 4\n addi s3, s3, 4\n j concat_1\nconcat_2:\n lw s1, 0(fp)\n lw s2, @.__len__(s1)\n addi s1, s1, @.__elts__\n\tlw s4, 8(fp)\nconcat_3:\n beqz s2, concat_4\n lw a0, 0(s1)\n\tjalr ra, s4, 0\n sw a0, 0(s3)\n addi s2, s2, -1\n addi s1, s1, 4\n addi s3, s3, 4\n j concat_3\nconcat_4:\n\tmv a0, s5\n lw s1, -12(fp)\n lw s2, -16(fp)\n lw s3, -20(fp)\n\tlw s4, -24(fp)\n lw s5, -28(fp)\n lw ra, -4(fp)\n lw fp, -8(fp)\n addi sp, sp, 32\n jr ra\nconcat_none:\n j error.None\n\n\n.globl conslist\nconslist:\n\n addi sp, sp, -8\n sw ra, 4(sp)\n sw fp, 0(sp)\n addi fp, sp, 8\n lw a1, 0(fp)\n la a0, $.list$prototype\n beqz a1, conslist_done\n addi a1, a1, @listHeaderWords\n jal alloc2\n lw t0, 0(fp)\n sw t0, @.__len__(a0)\n slli t1, t0, 2\n add t1, t1, fp\n addi t2, a0, @.__elts__\nconslist_1:\n lw t3, 0(t1)\n sw t3, 0(t2)\n addi t1, t1, -4\n addi t2, t2, 4\n addi t0, t0, -1\n bnez t0, conslist_1\nconslist_done:\n lw ra, -4(fp)\n lw fp, -8(fp)\n addi sp, sp, 8\n jr ra\n\n\n.globl strcat\nstrcat:\n\n addi sp, sp, -12\n sw ra, 8(sp)\n sw fp, 4(sp)\n addi fp, sp, 12\n lw t0, 4(fp)\n lw t1, 0(fp)\n lw t0, @.__len__(t0)\n beqz t0, strcat_4\n lw t1, @.__len__(t1)\n beqz t1, strcat_5\n add t1, t0, t1\n sw t1, -12(fp)\n addi t1, t1, 4\n srli t1, t1, 2\n addi a1, t1, @listHeaderWords\n la a0, $str$prototype\n jal alloc2\n lw t0, -12(fp)\n sw t0, @.__len__(a0)\n addi t2, a0, 16\n lw t0, 4(fp)\n lw t1, @.__len__(t0)\n addi t0, t0, @.__str__\nstrcat_1:\n beqz t1, strcat_2\n lbu t3, 0(t0)\n sb t3, 0(t2)\n addi t1, t1, -1\n addi t0, t0, 1\n addi t2, t2, 1\n j strcat_1\nstrcat_2:\n lw t0, 0(fp)\n lw t1, 12(t0)\n addi t0, t0, 16\nstrcat_3:\n beqz t1, strcat_6\n lbu t3, 0(t0)\n sb t3, 0(t2)\n addi t1, t1, -1\n addi t0, t0, 1\n addi t2, t2, 1\n j strcat_3\nstrcat_4:\n lw a0, 0(fp)\n j strcat_7\nstrcat_5:\n lw a0, 4(fp)\n j strcat_7\nstrcat_6:\n sb zero, 0(t2)\nstrcat_7:\n lw ra, -4(fp)\n lw fp, -8(fp)\n addi sp, sp, 12\n jr ra\n\n\n.globl streql\nstreql:\n\n addi sp, sp, -8\n sw ra, 4(sp)\n sw fp, 0(sp)\n addi fp, sp, 8\n lw a1, 4(fp)\n lw a2, 0(fp)\n lw t0, @.__len__(a1)\n lw t1, @.__len__(a2)\n bne t0, t1, streql_no\nstreql_1:\n lbu t2, @.__str__(a1)\n lbu t3, @.__str__(a2)\n bne t2, t3, streql_no\n addi a1, a1, 1\n addi a2, a2, 1\n addi t0, t0, -1\n bgtz t0, streql_1\n li a0, 1\n j streql_end\nstreql_no:\n xor a0, a0, a0\nstreql_end:\n lw ra, -4(fp)\n lw fp, -8(fp)\n addi sp, sp, 8\n jr ra\n\n\n.globl strneql\nstrneql:\n\n addi sp, sp, -8\n sw ra, 4(sp)\n sw fp, 0(sp)\n addi fp, sp, 8\n lw a1, 4(fp)\n lw a2, 0(fp)\n lw t0, @.__len__(a1)\n lw t1, @.__len__(a2)\n bne t0, t1, strneql_yes\nstrneql_1:\n lbu t2, @.__str__(a1)\n lbu t3, @.__str__(a2)\n bne t2, t3, strneql_yes\n addi a1, a1, 1\n addi a2, a2, 1\n addi t0, t0, -1\n bgtz t0, strneql_1\n xor a0, a0, a0\n j strneql_end\nstrneql_yes:\n li a0, 1\nstrneql_end:\n lw ra, -4(fp)\n lw fp, -8(fp)\n addi sp, sp, 8\n jr ra\n\n\n.globl makeint\nmakeint:\n\n addi sp, sp, -8\n sw ra, 4(sp)\n sw a0, 0(sp)\n la a0, $int$prototype\n jal ra, alloc\n lw t0, 0(sp)\n sw t0, @.__int__(a0)\n lw ra, 4(sp)\n addi sp, sp, 8\n jr ra\n\n\n.globl makebool\nmakebool:\n\n\tslli a0, a0, 4\n la t0, @bool.False\n add a0, a0, t0\n\tjr ra\n\n\n.globl noconv\nnoconv:\n\n jr ra\n\n\n.globl initchars\ninitchars:\n\n jr ra\n\n\n.globl error.None\nerror.None:\n li a0, 4 # Exit code for: Operation on None\n la a1, const_8 # Load error message as str\n addi a1, a1, 16 # Load address of attribute __str__\n j abort # Abort\n\n.globl error.Div\nerror.Div:\n li a0, 2 # Exit code for: Division by zero\n la a1, const_9 # Load error message as str\n addi a1, a1, 16 # Load address of attribute __str__\n j abort # Abort\n\n.globl error.OOB\nerror.OOB:\n li a0, 3 # Exit code for: Index out of bounds\n la a1, const_10 # Load error message as str\n addi a1, a1, 16 # Load address of attribute __str__\n j abort # Abort\n\n.data\n\n.globl const_0\nconst_0:\n .word 2 # Type tag for class: bool\n .word 4 # Object size\n .word $bool$dispatchTable # Pointer to dispatch table\n .word 0 # Constant value of attribute: __bool__\n .align 2\n\n.globl const_1\nconst_1:\n .word 2 # Type tag for class: bool\n .word 4 # Object size\n .word $bool$dispatchTable # Pointer to dispatch table\n .word 1 # Constant value of attribute: __bool__\n .align 2\n\n.globl const_3\nconst_3:\n .word 3 # Type tag for class: str\n .word 8 # Object size\n .word $str$dispatchTable # Pointer to dispatch table\n .word 15 # Constant value of attribute: __len__\n .string \"Item not found.\" # Constant value of attribute: __str__\n .align 2\n\n.globl const_9\nconst_9:\n .word 3 # Type tag for class: str\n .word 9 # Object size\n .word $str$dispatchTable # Pointer to dispatch table\n .word 16 # Constant value of attribute: __len__\n .string \"Division by zero\" # Constant value of attribute: __str__\n .align 2\n\n.globl const_7\nconst_7:\n .word 3 # Type tag for class: str\n .word 8 # Object size\n .word $str$dispatchTable # Pointer to dispatch table\n .word 13 # Constant value of attribute: __len__\n .string \"Out of memory\" # Constant value of attribute: __str__\n .align 2\n\n.globl const_10\nconst_10:\n .word 3 # Type tag for class: str\n .word 9 # Object size\n .word $str$dispatchTable # Pointer to dispatch table\n .word 19 # Constant value of attribute: __len__\n .string \"Index out of bounds\" # Constant value of attribute: __str__\n .align 2\n\n.globl const_5\nconst_5:\n .word 3 # Type tag for class: str\n .word 6 # Object size\n .word $str$dispatchTable # Pointer to dispatch table\n .word 4 # Constant value of attribute: __len__\n .string \"True\" # Constant value of attribute: __str__\n .align 2\n\n.globl const_8\nconst_8:\n .word 3 # Type tag for class: str\n .word 9 # Object size\n .word $str$dispatchTable # Pointer to dispatch table\n .word 17 # Constant value of attribute: __len__\n .string \"Operation on None\" # Constant value of attribute: __str__\n .align 2\n\n.globl const_2\nconst_2:\n .word 3 # Type tag for class: str\n .word 7 # Object size\n .word $str$dispatchTable # Pointer to dispatch table\n .word 11 # Constant value of attribute: __len__\n .string \"Item found!\" # Constant value of attribute: __str__\n .align 2\n\n.globl const_4\nconst_4:\n .word 3 # Type tag for class: str\n .word 9 # Object size\n .word $str$dispatchTable # Pointer to dispatch table\n .word 16 # Constant value of attribute: __len__\n .string \"Invalid argument\" # Constant value of attribute: __str__\n .align 2\n\n.globl const_6\nconst_6:\n .word 3 # Type tag for class: str\n .word 6 # Object size\n .word $str$dispatchTable # Pointer to dispatch table\n .word 5 # Constant value of attribute: __len__\n .string \"False\" # Constant value of attribute: __str__\n .align 2\n","cache_levels":"1","cache_current_level":"1","cache_L1_associativity":"1","cache_L1_cacheBlockSize":"4","cache_L1_numberOfBlocks":"1","cache_L1_placementPol":"DIRECT_MAPPING","cache_L1_blockRepPolicy":"LRU","cache_L1_seed":"-7788879576802893459","cache_L1_attach":"false","activeFileinEditor":"","active_abs_file_name":"n","active_abs_file_path":"n","fileExplorerCurrentLocation":"","terminalCurrentLocation":""}
# Compiled ChocoPy Program to RISC-V assembly # Execute (run or step-through) using the 'Simulator' tab above # Output will appear on the bottom-left of the simulator .equiv @sbrk, 9 .equiv @print_string, 4 .equiv @print_char, 11 .equiv @print_int, 1 .equiv @exit2, 17 .equiv @read_string, 8 .equiv @fill_line_buffer, 18 .equiv @.__obj_size__, 4 .equiv @.__len__, 12 .equiv @.__int__, 12 .equiv @.__bool__, 12 .equiv @.__str__, 16 .equiv @.__elts__, 16 .equiv @error_div_zero, 2 .equiv @error_arg, 1 .equiv @error_oob, 3 .equiv @error_none, 4 .equiv @error_oom, 5 .equiv @error_nyi, 6 .equiv @listHeaderWords, 4 .equiv @strHeaderWords, 4 .equiv @bool.True, const_1 .equiv @bool.False, const_0 .data .globl $object$prototype $object$prototype: .word 0 # Type tag for class: object .word 3 # Object size .word $object$dispatchTable # Pointer to dispatch table .align 2 .globl $int$prototype $int$prototype: .word 1 # Type tag for class: int .word 4 # Object size .word $int$dispatchTable # Pointer to dispatch table .word 0 # Initial value of attribute: __int__ .align 2 .globl $bool$prototype $bool$prototype: .word 2 # Type tag for class: bool .word 4 # Object size .word $bool$dispatchTable # Pointer to dispatch table .word 0 # Initial value of attribute: __bool__ .align 2 .globl $str$prototype $str$prototype: .word 3 # Type tag for class: str .word 5 # Object size .word $str$dispatchTable # Pointer to dispatch table .word 0 # Initial value of attribute: __len__ .word 0 # Initial value of attribute: __str__ .align 2 .globl $.list$prototype $.list$prototype: .word -1 # Type tag for class: .list .word 4 # Object size .word 0 # Pointer to dispatch table .word 0 # Initial value of attribute: __len__ .align 2 .globl $object$dispatchTable $object$dispatchTable: .word $object.__init__ # Implementation for method: object.__init__ .globl $int$dispatchTable $int$dispatchTable: .word $object.__init__ # Implementation for method: int.__init__ .globl $bool$dispatchTable $bool$dispatchTable: .word $object.__init__ # Implementation for method: bool.__init__ .globl $str$dispatchTable $str$dispatchTable: .word $object.__init__ # Implementation for method: str.__init__ .text .globl main main: lui a0, 8192 # Initialize heap size (in multiples of 4KB) add s11, s11, a0 # Save heap size jal heap.init # Call heap.init routine mv gp, a0 # Initialize heap pointer mv s10, gp # Set beginning of heap add s11, s10, s11 # Set end of heap (= start of heap + heap size) mv ra, zero # No normal return from main program. mv fp, zero # No preceding frame. mv fp, zero # Top saved FP is 0. mv ra, zero # No function return from top level. addi sp, sp, -@..main.size # Reserve space for stack frame. sw ra, @..main.size-4(sp) # return address sw fp, @..main.size-8(sp) # control link addi fp, sp, @..main.size # New fp is at old SP. jal initchars # Initialize one-character strings. li a0, 4 # Load integer literal 4 sw a0, -28(fp) # Push argument 5 from last. li a0, 8 # Load integer literal 8 sw a0, -32(fp) # Push argument 4 from last. li a0, 15 # Load integer literal 15 sw a0, -36(fp) # Push argument 3 from last. li a0, 16 # Load integer literal 16 sw a0, -40(fp) # Push argument 2 from last. li a0, 23 # Load integer literal 23 sw a0, -44(fp) # Push argument 1 from last. li a0, 5 # Pass list length sw a0, -48(fp) # Push argument 0 from last. addi sp, fp, -48 # Set SP to last argument. jal conslist # Move values to new list object addi sp, fp, -@..main.size # Set SP to stack frame top. sw a0, -12(fp) # Push argument 1 from last. li a0, 15 # Load integer literal 15 sw a0, -16(fp) # Push argument 0 from last. addi sp, fp, -16 # Set SP to last argument. jal $contains # Invoke function: contains addi sp, fp, -@..main.size # Set SP to stack frame top. beqz a0, label_2 # Branch on false. la a0, const_2 # Load string literal sw a0, -16(fp) # Push argument 0 from last. addi sp, fp, -16 # Set SP to last argument. jal $print # Invoke function: print addi sp, fp, -@..main.size # Set SP to stack frame top. j label_1 # Then body complete; jump to end-if label_2: # Else body la a0, const_3 # Load string literal sw a0, -16(fp) # Push argument 0 from last. addi sp, fp, -16 # Set SP to last argument. jal $print # Invoke function: print addi sp, fp, -@..main.size # Set SP to stack frame top. label_1: # End of if-else statement .equiv @..main.size, 48 label_0: # End of program li a0, 10 # Code for ecall: exit ecall .globl $object.__init__ $object.__init__: # Init method for type object. mv a0, zero # `None` constant jr ra # Return .globl $print $print: # Function print lw a0, 0(sp) # Load arg beq a0, zero, print_6 # None is an illegal argument lw t0, 0(a0) # Get type tag of arg li t1, 1 # Load type tag of `int` beq t0, t1, print_7 # Go to print(int) li t1, 3 # Load type tag of `str` beq t0, t1, print_8 # Go to print(str) li t1, 2 # Load type tag of `bool` beq t0, t1, print_9 # Go to print(bool) print_6: # Invalid argument li a0, 1 # Exit code for: Invalid argument la a1, const_4 # Load error message as str addi a1, a1, @.__str__ # Load address of attribute __str__ j abort # Abort # Printing bools print_9: # Print bool object in A0 lw a0, @.__bool__(a0) # Load attribute __bool__ beq a0, zero, print_10 # Go to: print(False) la a0, const_5 # String representation: True j print_8 # Go to: print(str) print_10: # Print False object in A0 la a0, const_6 # String representation: False j print_8 # Go to: print(str) # Printing strs. print_8: # Print str object in A0 addi a1, a0, @.__str__ # Load address of attribute __str__ j print_11 # Print the null-terminated string is now in A1 mv a0, zero # Load None j print_5 # Go to return print_11: # Print null-terminated string in A1 li a0, @print_string # Code for ecall: print_string ecall # Print string li a1, 10 # Load newline character li a0, @print_char # Code for ecall: print_char ecall # Print character j print_5 # Go to return # Printing ints. print_7: # Print int object in A0 lw a1, @.__int__(a0) # Load attribute __int__ li a0, @print_int # Code for ecall: print_int ecall # Print integer li a1, 10 # Load newline character li a0, 11 # Code for ecall: print_char ecall # Print character print_5: # End of function mv a0, zero # Load None jr ra # Return to caller .globl $len $len: # Function len # We do not save/restore fp/ra for this function # because we know that it does not use the stack or does not # call other functions. lw a0, 0(sp) # Load arg beq a0, zero, len_12 # None is an illegal argument lw t0, 0(a0) # Get type tag of arg li t1, 3 # Load type tag of `str` beq t0, t1, len_13 # Go to len(str) li t1, -1 # Load type tag for list objects beq t0, t1, len_13 # Go to len(list) len_12: # Invalid argument li a0, @error_arg # Exit code for: Invalid argument la a1, const_4 # Load error message as str addi a1, a1, @.__str__ # Load address of attribute __str__ j abort # Abort len_13: # Get length of string lw a0, @.__len__(a0) # Load attribute: __len__ jr ra # Return to caller .globl $input $input: addi sp, sp, -16 sw ra, 12(sp) sw fp, 8(sp) sw s1, 4(sp) addi fp, sp, 16 li a0, @fill_line_buffer ecall bgez a0, input_nonempty la a0, $str$prototype j input_done input_nonempty: mv s1, a0 addi t0, s1, 5 addi t0, t0, @.__str__ srli a1, t0, 2 la a0, $str$prototype jal ra, alloc2 sw s1, @.__len__(a0) mv a2, s1 mv s1, a0 addi a1, a0, @.__str__ li a0, @read_string ecall addi a0, a0, 1 sw a0, @.__len__(s1) add t0, a0, s1 li t1, 10 sb t1, @.__str__-1(t0) sb zero, @.__str__(t0) mv a0, s1 input_done: lw s1, -12(fp) lw ra, -4(fp) lw fp, -8(fp) addi sp, sp, 16 jr ra .globl $contains $contains: addi sp, sp, -@contains.size # Reserve space for stack frame. sw ra, @contains.size-4(sp) # return address sw fp, @contains.size-8(sp) # control link addi fp, sp, @contains.size # New fp is at old SP. li a0, 0 # Load integer literal 0 sw a0, -12(fp) # local variable i j label_6 # Jump to loop test label_5: # Top of while loop lw a0, 4(fp) # Load var: contains.items sw a0, -16(fp) # Push on stack slot 4 lw a0, -12(fp) # Load var: contains.i lw a1, -16(fp) # Pop stack slot 4 bnez a1, label_8 # Ensure not None j error.None # Go to error handler label_8: # Not None lw t0, 12(a1) # Load attribute: __len__ bltu a0, t0, label_9 # Ensure 0 <= index < len j error.OOB # Go to error handler label_9: # Index within bounds addi a0, a0, 4 # Compute list element offset in words li t0, 4 # Word size in bytes mul a0, a0, t0 # Compute list element offset in bytes add a0, a1, a0 # Pointer to list element lw a0, 0(a0) # Get list element sw a0, -16(fp) # Push on stack slot 4 lw a0, 0(fp) # Load var: contains.x lw t0, -16(fp) # Pop stack slot 4 bne t0, a0, label_7 # Branch on not == li a0, 1 # Load boolean literal: true j label_4 # Go to return label_7: # End of if-else statement lw a0, -12(fp) # Load var: contains.i sw a0, -16(fp) # Push on stack slot 4 li a0, 1 # Load integer literal 1 lw t0, -16(fp) # Pop stack slot 4 add a0, t0, a0 # Operator + sw a0, -12(fp) # Assign var: contains.i label_6: # Test loop condition lw a0, -12(fp) # Load var: contains.i sw a0, -16(fp) # Push on stack slot 4 lw a0, 4(fp) # Load var: contains.items sw a0, -32(fp) # Push argument 0 from last. addi sp, fp, -32 # Set SP to last argument. jal $len # Invoke function: len addi sp, fp, -@contains.size # Set SP to stack frame top. lw t0, -16(fp) # Pop stack slot 4 blt t0, a0, label_5 # Branch on < li a0, 0 # Load boolean literal: false j label_4 # Go to return mv a0, zero # Load None j label_4 # Jump to function epilogue label_4: # Epilogue .equiv @contains.size, 32 lw ra, -4(fp) # Get return address lw fp, -8(fp) # Use control link to restore caller's fp addi sp, sp, @contains.size # Restore stack pointer jr ra # Return to caller .globl alloc alloc: # Runtime support function alloc. # Prototype address is in a0. lw a1, 4(a0) # Get size of object in words j alloc2 # Allocate object with exact size .globl alloc2 alloc2: # Runtime support function alloc2 (realloc). # Prototype address is in a0. # Number of words to allocate is in a1. li a2, 4 # Word size in bytes mul a2, a1, a2 # Calculate number of bytes to allocate add a2, gp, a2 # Estimate where GP will move bgeu a2, s11, alloc2_15 # Go to OOM handler if too large lw t0, @.__obj_size__(a0) # Get size of object in words mv t2, a0 # Initialize src ptr mv t3, gp # Initialize dest ptr alloc2_16: # Copy-loop header lw t1, 0(t2) # Load next word from src sw t1, 0(t3) # Store next word to dest addi t2, t2, 4 # Increment src addi t3, t3, 4 # Increment dest addi t0, t0, -1 # Decrement counter bne t0, zero, alloc2_16 # Loop if more words left to copy mv a0, gp # Save new object's address to return sw a1, @.__obj_size__(a0) # Set size of new object in words # (same as requested size) mv gp, a2 # Set next free slot in the heap jr ra # Return to caller alloc2_15: # OOM handler li a0, @error_oom # Exit code for: Out of memory la a1, const_7 # Load error message as str addi a1, a1, @.__str__ # Load address of attribute __str__ j abort # Abort .globl abort abort: # Runtime support function abort (does not return). mv t0, a0 # Save exit code in temp li a0, @print_string # Code for print_string ecall ecall # Print error message in a1 li a1, 10 # Load newline character li a0, @print_char # Code for print_char ecall ecall # Print newline mv a1, t0 # Move exit code to a1 li a0, @exit2 # Code for exit2 ecall ecall # Exit with code abort_17: # Infinite loop j abort_17 # Prevent fallthrough .globl heap.init heap.init: # Runtime support function heap.init. mv a1, a0 # Move requested size to A1 li a0, @sbrk # Code for ecall: sbrk ecall # Request A1 bytes jr ra # Return to caller .globl concat concat: addi sp, sp, -32 sw ra, 28(sp) sw fp, 24(sp) addi fp, sp, 32 sw s1, -12(fp) sw s2, -16(fp) sw s3, -20(fp) sw s4, -24(fp) sw s5, -28(fp) lw t0, 4(fp) lw t1, 0(fp) beqz t0, concat_none beqz t1, concat_none lw t0, @.__len__(t0) lw t1, @.__len__(t1) add s5, t0, t1 addi a1, s5, @listHeaderWords la a0, $.list$prototype jal alloc2 sw s5, @.__len__(a0) mv s5, a0 addi s3, s5, @.__elts__ lw s1, 4(fp) lw s2, @.__len__(s1) addi s1, s1, @.__elts__ lw s4, 12(fp) concat_1: beqz s2, concat_2 lw a0, 0(s1) jalr ra, s4, 0 sw a0, 0(s3) addi s2, s2, -1 addi s1, s1, 4 addi s3, s3, 4 j concat_1 concat_2: lw s1, 0(fp) lw s2, @.__len__(s1) addi s1, s1, @.__elts__ lw s4, 8(fp) concat_3: beqz s2, concat_4 lw a0, 0(s1) jalr ra, s4, 0 sw a0, 0(s3) addi s2, s2, -1 addi s1, s1, 4 addi s3, s3, 4 j concat_3 concat_4: mv a0, s5 lw s1, -12(fp) lw s2, -16(fp) lw s3, -20(fp) lw s4, -24(fp) lw s5, -28(fp) lw ra, -4(fp) lw fp, -8(fp) addi sp, sp, 32 jr ra concat_none: j error.None .globl conslist conslist: addi sp, sp, -8 sw ra, 4(sp) sw fp, 0(sp) addi fp, sp, 8 lw a1, 0(fp) la a0, $.list$prototype beqz a1, conslist_done addi a1, a1, @listHeaderWords jal alloc2 lw t0, 0(fp) sw t0, @.__len__(a0) slli t1, t0, 2 add t1, t1, fp addi t2, a0, @.__elts__ conslist_1: lw t3, 0(t1) sw t3, 0(t2) addi t1, t1, -4 addi t2, t2, 4 addi t0, t0, -1 bnez t0, conslist_1 conslist_done: lw ra, -4(fp) lw fp, -8(fp) addi sp, sp, 8 jr ra .globl strcat strcat: addi sp, sp, -12 sw ra, 8(sp) sw fp, 4(sp) addi fp, sp, 12 lw t0, 4(fp) lw t1, 0(fp) lw t0, @.__len__(t0) beqz t0, strcat_4 lw t1, @.__len__(t1) beqz t1, strcat_5 add t1, t0, t1 sw t1, -12(fp) addi t1, t1, 4 srli t1, t1, 2 addi a1, t1, @listHeaderWords la a0, $str$prototype jal alloc2 lw t0, -12(fp) sw t0, @.__len__(a0) addi t2, a0, 16 lw t0, 4(fp) lw t1, @.__len__(t0) addi t0, t0, @.__str__ strcat_1: beqz t1, strcat_2 lbu t3, 0(t0) sb t3, 0(t2) addi t1, t1, -1 addi t0, t0, 1 addi t2, t2, 1 j strcat_1 strcat_2: lw t0, 0(fp) lw t1, 12(t0) addi t0, t0, 16 strcat_3: beqz t1, strcat_6 lbu t3, 0(t0) sb t3, 0(t2) addi t1, t1, -1 addi t0, t0, 1 addi t2, t2, 1 j strcat_3 strcat_4: lw a0, 0(fp) j strcat_7 strcat_5: lw a0, 4(fp) j strcat_7 strcat_6: sb zero, 0(t2) strcat_7: lw ra, -4(fp) lw fp, -8(fp) addi sp, sp, 12 jr ra .globl streql streql: addi sp, sp, -8 sw ra, 4(sp) sw fp, 0(sp) addi fp, sp, 8 lw a1, 4(fp) lw a2, 0(fp) lw t0, @.__len__(a1) lw t1, @.__len__(a2) bne t0, t1, streql_no streql_1: lbu t2, @.__str__(a1) lbu t3, @.__str__(a2) bne t2, t3, streql_no addi a1, a1, 1 addi a2, a2, 1 addi t0, t0, -1 bgtz t0, streql_1 li a0, 1 j streql_end streql_no: xor a0, a0, a0 streql_end: lw ra, -4(fp) lw fp, -8(fp) addi sp, sp, 8 jr ra .globl strneql strneql: addi sp, sp, -8 sw ra, 4(sp) sw fp, 0(sp) addi fp, sp, 8 lw a1, 4(fp) lw a2, 0(fp) lw t0, @.__len__(a1) lw t1, @.__len__(a2) bne t0, t1, strneql_yes strneql_1: lbu t2, @.__str__(a1) lbu t3, @.__str__(a2) bne t2, t3, strneql_yes addi a1, a1, 1 addi a2, a2, 1 addi t0, t0, -1 bgtz t0, strneql_1 xor a0, a0, a0 j strneql_end strneql_yes: li a0, 1 strneql_end: lw ra, -4(fp) lw fp, -8(fp) addi sp, sp, 8 jr ra .globl makeint makeint: addi sp, sp, -8 sw ra, 4(sp) sw a0, 0(sp) la a0, $int$prototype jal ra, alloc lw t0, 0(sp) sw t0, @.__int__(a0) lw ra, 4(sp) addi sp, sp, 8 jr ra .globl makebool makebool: slli a0, a0, 4 la t0, @bool.False add a0, a0, t0 jr ra .globl noconv noconv: jr ra .globl initchars initchars: jr ra .globl error.None error.None: li a0, 4 # Exit code for: Operation on None la a1, const_8 # Load error message as str addi a1, a1, 16 # Load address of attribute __str__ j abort # Abort .globl error.Div error.Div: li a0, 2 # Exit code for: Division by zero la a1, const_9 # Load error message as str addi a1, a1, 16 # Load address of attribute __str__ j abort # Abort .globl error.OOB error.OOB: li a0, 3 # Exit code for: Index out of bounds la a1, const_10 # Load error message as str addi a1, a1, 16 # Load address of attribute __str__ j abort # Abort .data .globl const_0 const_0: .word 2 # Type tag for class: bool .word 4 # Object size .word $bool$dispatchTable # Pointer to dispatch table .word 0 # Constant value of attribute: __bool__ .align 2 .globl const_1 const_1: .word 2 # Type tag for class: bool .word 4 # Object size .word $bool$dispatchTable # Pointer to dispatch table .word 1 # Constant value of attribute: __bool__ .align 2 .globl const_3 const_3: .word 3 # Type tag for class: str .word 8 # Object size .word $str$dispatchTable # Pointer to dispatch table .word 15 # Constant value of attribute: __len__ .string "Item not found." # Constant value of attribute: __str__ .align 2 .globl const_9 const_9: .word 3 # Type tag for class: str .word 9 # Object size .word $str$dispatchTable # Pointer to dispatch table .word 16 # Constant value of attribute: __len__ .string "Division by zero" # Constant value of attribute: __str__ .align 2 .globl const_7 const_7: .word 3 # Type tag for class: str .word 8 # Object size .word $str$dispatchTable # Pointer to dispatch table .word 13 # Constant value of attribute: __len__ .string "Out of memory" # Constant value of attribute: __str__ .align 2 .globl const_10 const_10: .word 3 # Type tag for class: str .word 9 # Object size .word $str$dispatchTable # Pointer to dispatch table .word 19 # Constant value of attribute: __len__ .string "Index out of bounds" # Constant value of attribute: __str__ .align 2 .globl const_5 const_5: .word 3 # Type tag for class: str .word 6 # Object size .word $str$dispatchTable # Pointer to dispatch table .word 4 # Constant value of attribute: __len__ .string "True" # Constant value of attribute: __str__ .align 2 .globl const_8 const_8: .word 3 # Type tag for class: str .word 9 # Object size .word $str$dispatchTable # Pointer to dispatch table .word 17 # Constant value of attribute: __len__ .string "Operation on None" # Constant value of attribute: __str__ .align 2 .globl const_2 const_2: .word 3 # Type tag for class: str .word 7 # Object size .word $str$dispatchTable # Pointer to dispatch table .word 11 # Constant value of attribute: __len__ .string "Item found!" # Constant value of attribute: __str__ .align 2 .globl const_4 const_4: .word 3 # Type tag for class: str .word 9 # Object size .word $str$dispatchTable # Pointer to dispatch table .word 16 # Constant value of attribute: __len__ .string "Invalid argument" # Constant value of attribute: __str__ .align 2 .globl const_6 const_6: .word 3 # Type tag for class: str .word 6 # Object size .word $str$dispatchTable # Pointer to dispatch table .word 5 # Constant value of attribute: __len__ .string "False" # Constant value of attribute: __str__ .align 2
The text was updated successfully, but these errors were encountered:
No branches or pull requests
The text was updated successfully, but these errors were encountered: