1 2// This is an older version of the Eat library. 3// I kept it because SpaceTode still uses it. 4 5// 6// Every result has three properties... 7// 8// 'success' 9// true if the desired thing was found 10// 11// 'snippet' 12// the desired thing 13// 14// 'code' 15// the rest of the code (with the desired thing removed) 16// 17 18EAT = {} 19HABITAT.EAT_LEGACY = true 20 21{ 22 23 //====================// 24 // Control Structures // 25 //====================// 26 EAT.many = (func) => (source, ...args) => { 27 28 // Buffers 29 let success = undefined 30 let code = source 31 32 // Head 33 let headResult = undefined 34 headResult = {success, code} = func(code, ...args) 35 if (!success) return {...headResult, code: source} 36 37 // Tail 38 let tailResult = undefined 39 tailResult = {success, code} = EAT.many(func)(code, ...args) 40 if (!success) return headResult 41 tailResult.snippet = headResult.snippet + tailResult.snippet 42 return tailResult 43 44 } 45 46 EAT.maybe = (func) => (source, ...args) => { 47 48 let result = undefined 49 let success = undefined 50 let code = source 51 52 result = {success, code} = func(code, ...args) 53 if (!success) { 54 result.success = true 55 result.snippet = "" 56 } 57 58 return result 59 } 60 61 EAT.list = (...funcs) => (source, ...args) => { 62 63 // Buffers 64 let success = undefined 65 let code = source 66 67 // Head 68 let headResult = undefined 69 const headFunc = funcs[0] 70 headResult = {success, code} = headFunc(code, ...args) 71 if (!success) return {...headResult, code: source} 72 73 // Tail 74 let tailResult = undefined 75 const tailFuncs = funcs.slice(1) 76 if (tailFuncs.length == 0) return headResult 77 tailResult = {success, code} = EAT.list(...tailFuncs)(code, ...args) 78 tailResult.snippet = headResult.snippet + tailResult.snippet 79 return tailResult 80 81 } 82 83 EAT.or = (...funcs) => (source, ...args) => { 84 85 for (const func of funcs) { 86 87 let result = undefined 88 let success = undefined 89 let code = source 90 91 result = {success, code} = func(code, ...args) 92 if (success) return result 93 } 94 95 const success = false 96 const code = source 97 const snippet = undefined 98 return {success, snippet, code} 99 } 100 101 EAT.fail = (source) => ({success: false, snippet: undefined, code: source}) 102 103 //====================// 104 // In-Built Functions // 105 //====================// 106 EAT.string = (string) => (source) => { 107 const success = source.slice(0, string.length) == string 108 const snippet = success? string : undefined 109 const code = success? source.slice(string.length) : source 110 return {success, snippet, code} 111 } 112 113 EAT.regexp = EAT.regExp = EAT.regex = EAT.regEx = (regex) => (source) => { 114 const fullRegex = new RegExp("^" + regex.source + "$") 115 116 let i = 0 117 while (i <= source.length) { 118 const snippet = source.slice(0, i) 119 const success = fullRegex.test(snippet) 120 if (success) { 121 const code = source.slice(snippet.length) 122 return {success, snippet, code} 123 } 124 i++ 125 } 126 127 const success = false 128 const snippet = undefined 129 const code = source 130 return {success, snippet, code} 131 132 } 133 134 EAT.space = EAT.string(" ") 135 EAT.tab = EAT.string(" ") 136 EAT.newline = EAT.newLine = EAT.string("\n") 137 138 EAT.gap = EAT.many ( 139 EAT.or ( 140 EAT.space, 141 EAT.tab, 142 ) 143 ) 144 145 EAT.whitespace = EAT.whiteSpace = EAT.many ( 146 EAT.or ( 147 EAT.space, 148 EAT.tab, 149 EAT.newline, 150 ) 151 ) 152 153 EAT.emptyLine = EAT.list ( 154 EAT.maybe(EAT.gap), 155 EAT.newline, 156 ) 157 158 EAT.emptyLines = EAT.many(EAT.emptyLine) 159 160 EAT.name = EAT.list ( 161 EAT.regexp(/[a-zA-Z_$]/), 162 EAT.many(EAT.regex(/[a-zA-Z0-9_$]/)) 163 ) 164 165 EAT.margin = EAT.or ( 166 EAT.many(EAT.tab), 167 EAT.many(EAT.space), 168 ) 169 170 EAT.line = EAT.many(EAT.regex(/[^\n]/)) 171}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.