summary refs log tree commit diff stats
path: root/compiler/lists.nim
blob: dd4f5d6be5c589a8c9535cb2e0468a17d98c9a08 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#
#
#           The Nimrod Compiler
#        (c) Copyright 2012 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

# This module implements a generic doubled linked list.

type 
  PListEntry* = ref TListEntry
  TListEntry* = object of TObject
    prev*, next*: PListEntry

  TStrEntry* = object of TListEntry
    data*: string

  PStrEntry* = ref TStrEntry
  TLinkedList* = object       # for the "find" operation:
    head*, tail*: PListEntry
    counter*: int

  TCompareProc* = proc (entry: PListEntry, closure: pointer): bool {.nimcall.}

proc initLinkedList*(list: var TLinkedList) = 
  list.counter = 0
  list.head = nil
  list.tail = nil

proc append*(list: var TLinkedList, entry: PListEntry) = 
  inc(list.counter)
  entry.next = nil
  entry.prev = list.tail
  if list.tail != nil: 
    assert(list.tail.next == nil)
    list.tail.next = entry
  list.tail = entry
  if list.head == nil: list.head = entry
  
proc contains*(list: TLinkedList, data: string): bool = 
  var it = list.head
  while it != nil: 
    if PStrEntry(it).data == data: 
      return true
    it = it.next
  
proc newStrEntry(data: string): PStrEntry = 
  new(result)
  result.data = data

proc appendStr*(list: var TLinkedList, data: string) = 
  append(list, newStrEntry(data))

proc includeStr*(list: var TLinkedList, data: string): bool = 
  if contains(list, data): return true
  appendStr(list, data)       # else: add to list

proc prepend*(list: var TLinkedList, entry: PListEntry) = 
  inc(list.counter)
  entry.prev = nil
  entry.next = list.head
  if list.head != nil: 
    assert(list.head.prev == nil)
    list.head.prev = entry
  list.head = entry
  if list.tail == nil: list.tail = entry

proc prependStr*(list: var TLinkedList, data: string) = 
  prepend(list, newStrEntry(data))

proc insertBefore*(list: var TLinkedList, pos, entry: PListEntry) = 
  assert(pos != nil)
  if pos == list.head: 
    prepend(list, entry)
  else: 
    inc(list.counter)
    entry.next = pos
    entry.prev = pos.prev
    if pos.prev != nil: pos.prev.next = entry
    pos.prev = entry
 
proc remove*(list: var TLinkedList, entry: PListEntry) = 
  dec(list.counter)
  if entry == list.tail: 
    list.tail = entry.prev
  if entry == list.head: 
    list.head = entry.next
  if entry.next != nil: entry.next.prev = entry.prev
  if entry.prev != nil: entry.prev.next = entry.next

proc bringToFront*(list: var TLinkedList, entry: PListEntry) =
  when true:
    list.remove entry
    list.prepend entry
  else:
    if entry == list.head: return
    if entry == list.tail: list.tail = entry.prev
    if entry.next != nil: entry.next.prev = entry.prev
    if entry.prev != nil: entry.prev.next = entry.next
    entry.prev = nil
    entry.next = list.head
    list.head = entry

proc excludeStr*(list: var TLinkedList, data: string) =
  var it = list.head
  while it != nil:
    let nxt = it.next
    if PStrEntry(it).data == data: remove(list, it)
    it = nxt

proc find*(list: TLinkedList, fn: TCompareProc, closure: pointer): PListEntry = 
  result = list.head
  while result != nil:
    if fn(result, closure): return 
    result = result.next
/span> <LI><CODE>Accumulate</CODE> <LI>Combining Higher-Order Functions <LI>Choosing the Right Tool <LI>First-Class Functions and First-Class Sentences <LI><CODE>Repeated</CODE> <LI>Pitfalls </UL> <H3>9. Lambda</H3> <UL> <LI>Procedures That Return Procedures <LI>The Truth about <CODE>Define</CODE> <LI>The Truth about <CODE>Let</CODE> <LI>Name Conflicts <LI>Named and Unnamed Functions <LI>Pitfalls </UL> <H3>Project: Scoring Bridge Hands</H3> <H3>10. Example: Tic-Tac-Toe</H3> <UL> <LI>A Warning <LI>Technical Terms in Tic-Tac-Toe <LI>Thinking about the Program Structure <LI>The First Step: Triples <LI>Finding the Triples <LI>Using <CODE>Every</CODE> with Two-Argument Procedures <LI>Can the Computer Win on This Move? <LI>If So, in Which Square? <LI>Second Verse, Same as the First <LI>Now the Strategy Gets Complicated <LI>Finding the Pivots <LI>Taking the Offensive <LI>Leftovers <LI>Complete Program Listing </UL> <A HREF="https://people.eecs.berkeley.edu/~bh/part4.html"><H2>Part IV. Recursion</H2></A> <H3>11. Introduction to Recursion</H3> <UL> <LI>A Separate Procedure for Each Length <LI>Use What You Have to Get What You Need <LI>Notice That They're All the Same <LI>Notice That They're Almost All the Same <LI>Base Cases and Recursive Calls <LI>Pig Latin <LI>Problems for You to Try <LI>Our Solutions <LI>Pitfalls </UL> <H3>12. The Leap of Faith</H3> <UL> <LI>From the Combining Method to the Leap of Faith <LI>Example: <CODE>Reverse</CODE> <LI>The Leap of Faith <LI>The Base Case <LI>Example: <CODE>Factorial</CODE> <LI>Likely Guesses for Smaller Subproblems <LI>Example: <CODE>Downup</CODE> <LI>Example: <CODE>Evens</CODE> <LI>Simplifying Base Cases <LI>Pitfalls </UL> <H3>13. How Recursion Works</H3> <UL> <LI>Little People and Recursion <LI>Tracing <LI>Pitfalls </UL> <H3>14. Common Patterns in Recursive Procedures</H3> <UL> <LI>The <CODE>Every</CODE> Pattern <LI>The <CODE>Keep</CODE> Pattern <LI>The <CODE>Accumulate</CODE> Pattern <LI>Combining Patterns <LI>Helper Procedures <LI>How to Use Recursive Patterns <LI>Problems That Don't Follow Patterns <LI>Pitfalls </UL> <H3>Project: Spelling Names of Huge Numbers</H3> <H3>15. Advanced Recursion</H3> <UL> <LI>Example: <CODE>Sort</CODE> <LI>Example: <CODE>From-Binary</CODE> <LI>Example: <CODE>Mergesort</CODE> <LI>Example: <CODE>Subsets</CODE> <LI>Pitfalls </UL> <H3>Project: Scoring Poker Hands</H3> <UL> <LI>Extra Work for Hotshots </UL> <H3>16. Example: Pattern Matcher</H3> <UL> <LI>Problem Description <LI>Implementation: When Are Two Sentences Equal? <LI>When Are Two Sentences Nearly Equal? <LI>Matching with Alternatives <LI>Backtracking <LI>Matching Several Words <LI>Combining the Placeholders <LI>Naming the Matched Text <LI>The Final Version <LI>Abstract Data Types <LI>Backtracking and <CODE>Known-Values</CODE> <LI>How We Wrote It <LI>Complete Program Listing </UL> <A HREF="part5.html"><H2>Part V. Abstraction</H2></A> <H3>17. Lists</H3> <UL> <LI>Selectors and Constructors <LI>Programming with Lists <LI>The Truth about Sentences <LI>Higher-Order Functions <LI>Other Primitives for Lists <LI>Association Lists <LI>Functions That Take Variable Numbers of Arguments <LI>Recursion on Arbitrary Structured Lists <LI>Pitfalls </UL> <H3>18. Trees</H3> <UL> <LI>Example: The World <LI>How Big Is My Tree? <LI>Mutual Recursion <LI>Searching for a Datum in the Tree <LI>Locating a Datum in the Tree <LI>Representing Trees as Lists <LI>Abstract Data Types <LI>An Advanced Example: Parsing Arithmetic Expressions <LI>Pitfalls </UL> <H3>19. Implementing Higher-Order Functions</H3> <UL> <LI>Generalizing Patterns <LI>The <CODE>Every</CODE> Pattern Revisited <LI>The Difference between <CODE>Map</CODE> and <CODE>Every</CODE> <LI><CODE>Filter</CODE> <LI><CODE>Accumulate</CODE> and <CODE>Reduce</CODE> <LI>Robustness <LI>Higher-Order Functions for Structured Lists <LI>The Zero-Trip Do Loop <LI>Pitfalls </UL> <A HREF="part6.html"><H2>Part VI. Sequential Programming</H2></A> <H3>20. Input and Output</H3> <UL> <LI>Printing <LI>Side Effects and Sequencing <LI>The <CODE>Begin</CODE> Special Form <LI>This Isn't Functional Programming <LI>Not Moving to the Next Line <LI>Strings <LI>A Higher-Order Procedure for Sequencing <LI>Tic-Tac-Toe Revisited <LI>Accepting User Input <LI>Aesthetic Board Display <LI>Reading and Writing Normal Text <LI>Formatted Text <LI>Sequential Programming and Order of Evaluation <LI>Pitfalls </UL> <H3>21. Example: The <CODE>Functions</CODE> Program</H3> <UL> <LI>The Main Loop <LI>The Difference between a Procedure and Its Name <LI>The Association List of Functions <LI>Domain Checking <LI>Intentionally Confusing a Function with Its Name <LI>More on Higher-Order Functions <LI>More Robustness <LI>Complete Program Listing </UL> <H3>22. Files</H3> <UL> <LI>Ports <LI>Writing Files for People to Read <LI>Using a File as a Database <LI>Transforming the Lines of a File <LI>Justifying Text <LI>Preserving Spacing of Text from Files <LI>Merging Two Files <LI>Writing Files for Scheme to Read <LI>Pitfalls </UL> <H3>23. Vectors</H3> <UL> <LI>The Indy 500 <LI>Vectors <LI>Using Vectors in Programs <LI>Non-Functional Procedures and State <LI>Shuffling a Deck <LI>More Vector Tools <LI>The Vector Pattern of Recursion <LI>Vectors versus Lists <LI>State, Sequence, and Effects <LI>Pitfalls </UL> <H3>24. Example: A Spreadsheet Program</H3> <UL> <LI>Limitations of Our Spreadsheet <LI>Spreadsheet Commands <LI>Moving the Selection <LI>Putting Values in Cells <LI>Formulas <LI>Displaying Formula Values <LI>Loading Spreadsheet Commands from a File <LI>Application Programs and Abstraction </UL> <H3>25. Implementing the Spreadsheet Program</H3> <UL> <LI>Cells, Cell Names, and Cell IDs <LI>The Command Processor <LI>Cell Selection Commands <LI>The <CODE>Load</CODE> Command <LI>The <CODE>Put</CODE> Command <LI>The Formula Translator <LI>The Dependency Manager <LI>The Expression Evaluator <LI>The Screen Printer <LI>The Cell Manager <LI>Complete Program Listing </UL> <H3>Project: A Database Program</H3> <UL> <LI>A Sample Session with Our Database <LI>How Databases Are Stored Internally <LI>The Current Database <LI>Implementing the Database Program Commands <LI>Additions to the Program <LI>Extra Work for Hotshots </UL> <A HREF="part7.html"><H2>Part VII. Conclusion: Computer Science</H2></A> <H3>26. What's Next?</H3> <UL> <LI>The Best Computer Science Book <LI>Beyond <CITE>SICP</CITE> <LI>Standard Scheme <LI>Last Words </UL> <H2>Appendices</H2> <H3>A. Running Scheme</H3> <UL> <LI>The Program Development Cycle <LI>Integrated Editing <LI>Getting Our Programs <LI>Tuning Our Programs for Your System <LI>Loading Our Programs <LI>Versions of Scheme <LI>Scheme Standards </UL> <H3>B. Common Lisp</H3> <UL> <LI>Why Common Lisp Exists <LI>Defining Procedures and Variables <LI>The Naming Convention for Predicates <LI>No Words or Sentences <LI>True and False <LI>Files <LI>Arrays <LI>Equivalents to Scheme Primitives <LI>A Separate Name Space for Procedures <LI><CODE>Lambda</CODE> <LI>More about <CODE>Function</CODE> <LI>Writing Higher-Order Procedures </UL> <H3>C. Scheme Initialization File</H3> <H3>D. GNU General Public License</H3> <H3>Credits</H3> <H3>Alphabetical Table of Scheme Primitives</H3> <H3>Glossary</H3> <H3>Index of Defined Procedures</H3> <H3>General Index</H3> <P> <A HREF="http://mitpress.mit.edu/0262082810">MIT Press web page for <CITE>Simply Scheme</CITE></A> <P> <ADDRESS> <A HREF="index.html">Brian Harvey</A>, <CODE>bh@cs.berkeley.edu</CODE> </ADDRESS> <BR> <ADDRESS> <A HREF="http://www.cnmat.berkeley.edu/~matt">Matthew Wright</A>, <CODE>matt@cnmat.berkeley.edu</CODE> </ADDRESS> </BODY> </HTML>