Guest User

Single_Linked_List.t

a guest
May 30th, 2021
1,323
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.84 KB | None | 0 0
  1. -- Single_Linked_List.t: Implementation in "Terra"
  2.  
  3. local C = terralib.includecstring [[
  4.         #include <stdio.h>
  5.         #include <stdlib.h>
  6. ]]
  7.  
  8. local function List(T, Options)
  9.  
  10.     local function check_allocator(opt)
  11.         return opt and opt.allocator and opt.allocator.alloc and opt.allocator.dealloc
  12.     end
  13.  
  14.     local alloc = macro(
  15.         function(arg)
  16.             if check_allocator(Options) then
  17.                 return `Options.allocator.alloc(arg)
  18.             else
  19.                 print("DEBUG: macro alloc  : Using default C.malloc")
  20.                 return `C.malloc(arg)
  21.             end
  22.         end
  23.     )
  24.  
  25.     local dealloc = macro(
  26.         function(arg)
  27.             if check_allocator(Options) then
  28.                 return `Options.allocator.dealloc(arg)
  29.             else
  30.                 print("DEBUG: macro dealloc: Using default C.free")
  31.                 return `C.free(arg)
  32.             end
  33.         end
  34.     )
  35.  
  36.     local log = macro(
  37.         function(fmt, arg)
  38.             if Options and Options.allocator and Options.allocator.logging then
  39.                 return `C.printf(fmt, arg)
  40.             else
  41.                 print("DEBUG: macro log    : Disabling logging (default)")
  42.                 return `nil
  43.             end
  44.         end
  45.     )
  46.  
  47.     local print_data = macro(
  48.         function(arg)
  49.             if Options and Options.print and Options.print.data then
  50.                 return `Options.print.data(arg)
  51.             elseif T:isintegral() then
  52.                 if T == uint64 then
  53.                     return `C.printf("%llu", arg)
  54.                 else
  55.                     return `C.printf("%lld", [int64](arg))
  56.                 end
  57.             elseif T:isfloat() then
  58.                 return `C.printf("%.1lf", [double](arg))
  59.             elseif T == &int8 then
  60.                 return `C.printf("\"%s\"", arg)
  61.             else
  62.                 print("WARN: print_data macro: Fall back to generic '<val>'")
  63.                 return `C.printf("<val>")
  64.             end
  65.         end
  66.     )
  67.  
  68.     local function print_max_nodes()
  69.         if Options and Options.print and Options.print.max_nodes then
  70.             return Options.print.max_nodes
  71.         else
  72.             return 3
  73.         end
  74.     end
  75.  
  76.     local function Node(T)
  77.         local struct Node {
  78.             data: T
  79.             next: &Node
  80.         }
  81.  
  82.         terra Node:init(data: T, next: &Node)
  83.             self.data = data
  84.             self.next = next
  85.         end
  86.  
  87.         terra Node:get_data(): T
  88.             return self.data
  89.         end
  90.  
  91.         terra Node:get_next(): &Node
  92.             return self.next
  93.         end
  94.  
  95.         terra Node:print_debug()
  96.             var p_node: &Node = self
  97.             var count: uint32 = 0
  98.             while (p_node ~= nil) and (count < [ print_max_nodes() ]) do
  99.                 C.printf("Node { data: ")
  100.                 print_data(p_node.data)
  101.                 C.printf(", next: ")
  102.                 p_node = p_node.next
  103.                 count = count + 1
  104.             end
  105.             if p_node == nil then -- reached end
  106.                 C.printf("NULL")
  107.             else -- count reached limit
  108.                 C.printf("...")
  109.             end
  110.             if count > 0 then
  111.                 C.printf(" ")
  112.                 for i = 0, count do
  113.                     C.printf("}")
  114.                 end
  115.             end
  116.         end
  117.  
  118.         terra Node:print()
  119.             var p_node: &Node = self
  120.             var count: uint32 = 0
  121.             while (p_node ~= nil) and (count < [ print_max_nodes() ]) do
  122.                 print_data(p_node.data)
  123.                 p_node = p_node.next
  124.                 if p_node ~= nil then
  125.                     C.printf(", ")
  126.                 end
  127.                 count = count + 1
  128.             end
  129.             if p_node ~= nil then --count reached limit
  130.                 C.printf("...")
  131.             end
  132.         end
  133.  
  134.         return Node
  135.     end -- Node(T)
  136.  
  137.     local Node_of_T = Node(T)
  138.  
  139.     local struct List {
  140.         head: &Node_of_T
  141.         len: int
  142.     }
  143.  
  144.     terra List:init()
  145.         self.head = nil
  146.         self.len  = 0
  147.     end
  148.  
  149.     terra List:get_head(): &Node_of_T
  150.         return self.head
  151.     end
  152.  
  153.     terra List:get_len(): int
  154.         return self.len
  155.     end
  156.  
  157.     terra List:cons(data: T): bool
  158.         var ptr: &opaque = alloc(sizeof(Node_of_T))
  159.         if ptr == nil then
  160.             C.printf("\nERROR: terra List:cons() : Could not alloc Node_of_T\n")
  161.             return false
  162.         else
  163.             var p_node: &Node_of_T = [&Node_of_T](ptr)
  164.             log("DEBUG: terra List:cons(): ALLOC node at %p\n", p_node)
  165.             p_node:init(data, self.head)
  166.             self.head = p_node
  167.             self.len = self.len + 1
  168.             return true
  169.         end
  170.     end
  171.  
  172.     terra List:dealloc()
  173.         var p_node: &Node_of_T = self.head
  174.         while p_node ~= nil do
  175.             self.head = (self.head):get_next()
  176.             log("DEBUG: terra List:dealloc(): DEALLOC node at %p\n", p_node)
  177.             dealloc(p_node)
  178.             p_node = self.head
  179.         end
  180.     end
  181.  
  182.     terra List:print_debug()
  183.         C.printf("List { head: ")
  184.         (self.head):print_debug()
  185.         C.printf(", len: %d }", self.len)
  186.     end
  187.  
  188.     terra List:print()
  189.         C.printf("[")
  190.         (self.head):print()
  191.         C.printf("] (len: %d)", self.len)
  192.     end
  193.  
  194.     return List
  195. end -- List(T)
  196.  
  197. ------------------------------- TESTING --------------------------------------
  198.  
  199. print("\nDEBUG: List_int")
  200. local List_int = List(int)
  201.  
  202. terra print_custom_float(data: float)
  203.     C.printf("%+0.3f", data)
  204. end
  205.  
  206. print("\nDEBUG: List_float")
  207. local List_float = List(float, {
  208.     allocator = { alloc = C.malloc, dealloc = C.free, logging = true },
  209.     print     = { data = print_custom_float, max_nodes = 4 }
  210. })
  211.  
  212. print("\nDEBUG: List_string")
  213. local List_string = List(&int8, {
  214.     allocator = { logging = true }
  215. })
  216.  
  217. print("\nDEBUG: terra test_single_linked_list()")
  218. terra test_single_linked_list()
  219.     var int_list: List_int
  220.     int_list:init()
  221.  
  222.     var float_list: List_float
  223.     float_list:init()
  224.  
  225.     var string_list: List_string
  226.     string_list:init()
  227.  
  228.     var err_msg: &int8 = nil
  229.     ------
  230.     C.printf("\nDEBUG: int_list:initial state:\n")
  231.     int_list:print()
  232.  
  233.     C.printf("\n\nDEBUG: int_list (dbg) = ")
  234.     int_list:print_debug()
  235.  
  236.     C.printf("\n\nDEBUG: int_list:cons(i) for i in range(0, 100):\n")
  237.     for i = 0, 100 do
  238.         if not (int_list:cons(i)) then
  239.             err_msg = "ERROR: int_list:cons(i) FAILED"
  240.             goto cleanup
  241.         end
  242.     end
  243.     int_list:print()
  244.  
  245.     C.printf("\n\nDEBUG: int_list (dbg) = ")
  246.     int_list:print_debug()
  247.     ------
  248.     C.printf("\n\nDEBUG: float_list:initial state:\n")
  249.     float_list:print()
  250.  
  251.     C.printf("\n\nDEBUG: float_list (dbg) = ")
  252.     float_list:print_debug()
  253.  
  254.     C.printf("\n\nDEBUG: float_list:cons(i) for i in range(0, 6):\n")
  255.     for i = 0, 6 do
  256.         if not (float_list:cons(i)) then
  257.             err_msg = "ERROR: float_list:cons(i) FAILED"
  258.             goto cleanup
  259.         end
  260.     end
  261.     float_list:print()
  262.  
  263.     C.printf("\n\nDEBUG: float_list (dbg) = ")
  264.     float_list:print_debug()
  265.     ------
  266.     C.printf("\n\nDEBUG: string_list:initial state:\n")
  267.     string_list:print()
  268.  
  269.     C.printf("\n\nDEBUG: string_list (dbg) = ")
  270.     string_list:print_debug()
  271.     C.printf("\n\nDEBUG: string_list (after cons: 'abc', 'def', 'ghi'):\n")
  272.  
  273.     err_msg = "ERROR: string_list:cons(...) FAILED"
  274.     if not (string_list:cons("abc")) then goto cleanup end
  275.     if not (string_list:cons("def")) then goto cleanup end
  276.     if not (string_list:cons("ghi")) then goto cleanup end
  277.     err_msg = nil
  278.  
  279.     string_list:print()
  280.  
  281.     C.printf("\n\nDEBUG: string_list (dbg) = ")
  282.     string_list:print_debug()
  283.     ------
  284.     ::cleanup::
  285.     C.printf("\n\nDEBUG: int_list:dealloc()\n")
  286.     int_list:dealloc()
  287.     C.printf("\n\nDEBUG: float_list:dealloc()\n")
  288.     float_list:dealloc()
  289.     C.printf("\n\nDEBUG: string_list:dealloc()\n")
  290.     string_list:dealloc()
  291.  
  292.     if err_msg ~= nil then
  293.         C.printf(err_msg)
  294.         return C.EXIT_FAILURE
  295.     else
  296.         return C.EXIT_SUCCESS
  297.     end
  298. end
  299.  
  300. --test_single_linked_list:printpretty()
  301. --test_single_linked_list:disas()
  302.  
  303. test_single_linked_list()
  304.  
  305. terralib.saveobj("test_single_linked_list.exe", {
  306.     main = test_single_linked_list
  307. })
  308.  
Advertisement
Add Comment
Please, Sign In to add comment