summary refs log tree commit diff stats
path: root/compiler/semgnrc.nim
Commit message (Expand)AuthorAgeFilesLines
...
* fixes #1444Araq2014-08-311-7/+13
* updated the compiler to use the new symbol namesAraq2014-08-281-4/+4
* Nimrod renamed to NimAraq2014-08-281-1/+1
* the big renamefest: first stepsAraq2014-08-221-2/+2
* fixes latest regressionAraq2014-07-111-1/+1
* fixes #1011Araq2014-07-091-3/+34
* Renamed considerAccents to considerQuotedIdentClay Sweetser2014-05-261-2/+2
* Renamed 'considerAcc' to 'considerAccents' for clarityClay Sweetser2014-05-241-2/+2
* compiler prepared for the new comment handlingAraq2014-04-301-0/+1
* propagate semExpr flags in macro/template expansionZahary Karadjov2014-04-061-4/+4
* fixes wrong commitAraq2014-03-221-2/+0
* fixes #1006Araq2014-03-221-0/+2
* split the inline and closure iterators into different symbol kinds for easier...Zahary Karadjov2014-03-061-2/+2
* fixes 'newSeq[T]' instantiation bugAraq2014-02-091-7/+4
* it's the year 2014Araq2014-01-191-3/+3
* introduce tyFromExpr; fixes #618Zahary Karadjov2014-01-041-7/+0
* case consistency part 4Araq2013-12-271-9/+9
* case consistency part 1Araq2013-12-271-1/+1
* fixes #531Araq2013-07-241-1/+1
* Merge branch 'master' of github.com:Araq/NimrodAraq2013-05-141-16/+16
|\
| * get rid of the SymTab* procs in astalgoZahary Karadjov2013-05-121-2/+2
| * switch to a linked list of scopesZahary Karadjov2013-05-111-14/+14
* | todo.txt changesAraq2013-05-111-5/+0
|/
* Removes executable bit for text files.Grzegorz Adam Hankiewicz2013-03-161-0/+0
* bugfix: 'indexOf' for tuple fields worksAraq2013-03-111-5/+0
* fixes for the new overloading resolutionAraq2013-03-031-5/+10
* bugfix: threads should work again; fixes #220Araq2012-10-121-4/+5
* allow 'mixin' in genericsAraq2012-10-121-50/+69
* syntax compatibility between do blocks and stmt blocksZahary Karadjov2012-10-041-11/+2
* the `is` operator now works with type classes and type variablesZahary Karadjov2012-10-031-10/+10
* bugfix: allow tuple constructors in generic codeZahary Karadjov2012-10-031-0/+3
* fixes #194Araq2012-09-201-1/+8
* bugfix: 'defined/compiles' open an implicit mixin scope in genericsAraq2012-09-181-3/+6
* made tests green againAraq2012-09-181-5/+12
* stricter symbol lookup in genericsAraq2012-09-171-8/+10
* first steps for overloading support of passing blocks; bugfix: test results o...Araq2012-09-111-6/+29
* parameter passing works the same for macros and templates; use callsite magic...Araq2012-08-281-2/+2
* distinguish properly between nkOpen and nkClosedSymChoiceAraq2012-08-261-6/+7
* next steps to hygienic templatesAraq2012-08-201-1/+1
* first steps to make templates hygienicAraq2012-08-201-11/+11
* bugfix: bind context for genericsAraq2012-07-241-3/+3
* added system.||; lacks runtime supportAraq2012-05-231-1/+1
* experimental support for preserving local variable names in the generated codeZahary Karadjov2012-04-131-0/+2
* `do' keyword in the grammar for lambda blocksZahary Karadjov2012-02-101-2/+2
* bugfix: removed newSons legacyAraq2012-01-071-1/+2
* year 2012 for most copyright headersAraq2012-01-021-1/+1
* bugfix: preliminary symbol declaration in first pass of genericsAraq2011-12-301-9/+11
* implemented 'let' statementAraq2011-11-291-1/+1
* small bugfixes to make more tests greenAraq2011-11-021-2/+4
* lazy loading of body ast implementedAraq2011-10-301-2/+3
nals import SignalDispatcher import math import os.path import sys import select try: import chardet HAVE_CHARDET = True except: HAVE_CHARDET = False class Loadable(object): paused = False progressbar_supported = False def __init__(self, gen, descr): self.load_generator = gen self.description = descr self.percent = 0 def get_description(self): return self.description def pause(self): self.paused = True def unpause(self): try: del self.paused except: pass def destroy(self): pass class CopyLoader(Loadable, FileManagerAware): progressbar_supported = True def __init__(self, copy_buffer, do_cut=False, overwrite=False): self.copy_buffer = tuple(copy_buffer) self.do_cut = do_cut self.original_copy_buffer = copy_buffer self.original_path = self.fm.thistab.path self.overwrite = overwrite self.percent = 0 if self.copy_buffer: self.one_file = self.copy_buffer[0] Loadable.__init__(self, self.generate(), 'Calculating size...') def _calculate_size(self, step): from os.path import join size = 0 stack = [f.path for f in self.copy_buffer] while stack: fname = stack.pop() if os.path.islink(fname): continue if os.path.isdir(fname): stack.extend([join(fname, item) for item in os.listdir(fname)]) else: try: fstat = os.stat(fname) except: continue size += max(step, math.ceil(fstat.st_size / step) * step) return size def generate(self): from ranger.ext import shutil_generatorized as shutil_g if self.copy_buffer: # TODO: Don't calculate size when renaming (needs detection) bytes_per_tick = shutil_g.BLOCK_SIZE size = max(1, self._calculate_size(bytes_per_tick)) bar_tick = 100.0 / (float(size) / bytes_per_tick) if self.do_cut: self.original_copy_buffer.clear() if len(self.copy_buffer) == 1: self.description = "moving: " + self.one_file.path else: self.description = "moving files from: " + self.one_file.dirname for f in self.copy_buffer: for tf in self.fm.tags.tags: if tf == f.path or str(tf).startswith(f.path): tag = self.fm.tags.tags[tf] self.fm.tags.remove(tf) self.fm.tags.tags[tf.replace(f.path, self.original_path \ + '/' + f.basename)] = tag self.fm.tags.dump() for _ in shutil_g.move(src=f.path, dst=self.original_path, overwrite=self.overwrite): self.percent += bar_tick yield else: if len(self.copy_buffer) == 1: self.description = "copying: " + self.one_file.path else: self.description = "copying files from: " + self.one_file.dirname for f in self.copy_buffer: if os.path.isdir(f.path) and not os.path.islink(f.path): for _ in shutil_g.copytree(src=f.path, dst=os.path.join(self.original_path, f.basename), symlinks=True, overwrite=self.overwrite): self.percent += bar_tick yield else: for _ in shutil_g.copy2(f.path, self.original_path, symlinks=True, overwrite=self.overwrite): self.percent += bar_tick yield cwd = self.fm.get_directory(self.original_path) cwd.load_content() class CommandLoader(Loadable, SignalDispatcher, FileManagerAware): """Run an external command with the loader. Output from stderr will be reported. Ensure that the process doesn't ever ask for input, otherwise the loader will be blocked until this object is removed from the queue (type ^C in ranger) """ finished = False process = None def __init__(self, args, descr, silent=False, read=False, input=None, kill_on_pause=False): SignalDispatcher.__init__(self) Loadable.__init__(self, self.generate(), descr) self.args = args self.silent = silent self.read = read self.stdout_buffer = "" self.input = input self.kill_on_pause = kill_on_pause def generate(self): py3 = sys.version_info[0] >= 3 if self.input: stdin = PIPE else: stdin = open(os.devnull, 'r') self.process = process = Popen(self.args, stdout=PIPE, stderr=PIPE, stdin=stdin) self.signal_emit('before', process=process, loader=self) if self.input: if py3: import io stdin = io.TextIOWrapper(process.stdin) else: stdin = process.stdin try: stdin.write(self.input) except IOError as e: if e.errno != errno.EPIPE and e.errno != errno.EINVAL: raise stdin.close() if self.silent and not self.read: while process.poll() is None: yield if self.finished: break sleep(0.03) else: selectlist = [] if self.read: selectlist.append(process.stdout) if not self.silent: selectlist.append(process.stderr) while process.poll() is None: yield if self.finished: break try: rd, _, __ = select.select(selectlist, [], [], 0.03) if rd: rd = rd[0] if rd == process.stderr: read = rd.readline() if py3: read = safeDecode(read) if read: self.fm.notify(read, bad=True) elif rd == process.stdout: read = rd.read(512) if py3: read = safeDecode(read) if read: self.stdout_buffer += read except select.error: sleep(0.03) if not self.silent: for l in process.stderr.readlines(): if py3: l = safeDecode(l) self.fm.notify(l, bad=True) if self.read: read = process.stdout.read() if py3: read = safeDecode(read) self.stdout_buffer += read self.finished = True self.signal_emit('after', process=process, loader=self) def pause(self): if not self.finished and not self.paused: if self.kill_on_pause: self.finished = True try: self.process.kill() except OSError: # probably a race condition where the process finished # between the last poll()ing and this point. pass return try: self.process.send_signal(20) except: pass Loadable.pause(self) self.signal_emit('pause', process=self.process, loader=self) def unpause(self): if not self.finished and self.paused: try: self.process.send_signal(18) except: pass Loadable.unpause(self) self.signal_emit('unpause', process=self.process, loader=self) def destroy(self): self.signal_emit('destroy', process=self.process, loader=self) if self.process: try: self.process.kill() except OSError: pass def safeDecode(string): try: return string.decode("utf-8") except (UnicodeDecodeError): if HAVE_CHARDET: return string.decode(chardet.detect(string)["encoding"]) else: return "" class Loader(FileManagerAware): seconds_of_work_time = 0.03 throbber_chars = r'/-\|' throbber_paused = '#' paused = False def __init__(self): self.queue = deque() self.item = None self.load_generator = None self.throbber_status = 0 self.rotate() self.old_item = None def rotate(self): """Rotate the throbber""" # TODO: move all throbber logic to UI self.throbber_status = \ (self.throbber_status + 1) % len(self.throbber_chars) self.status = self.throbber_chars[self.throbber_status] def add(self, obj): """Add an object to the queue. It should have a load_generator method. """ while obj in self.queue: self.queue.remove(obj) self.queue.appendleft(obj) if self.paused: obj.pause() else: obj.unpause() def move(self, _from, to): try: item = self.queue[_from] except IndexError: return del self.queue[_from] if to == 0: self.queue.appendleft(item) if _from != 0: self.queue[1].pause() elif to == -1: self.queue.append(item) else: raise NotImplementedError def remove(self, item=None, index=None): if item is not None and index is None: for i, test in enumerate(self.queue): if test == item: index = i break else: return if index is not None: if item is None: item = self.queue[index] if hasattr(item, 'unload'): item.unload() item.destroy() del self.queue[index] if item.progressbar_supported: self.fm.ui.status.request_redraw() def pause(self, state): """Change the pause-state to 1 (pause), 0 (no pause) or -1 (toggle)""" if state == -1: state = not self.paused elif state == self.paused: return self.paused = state if not self.queue: return if state: self.queue[0].pause() else: self.queue[0].unpause() def work(self): """Load items from the queue if there are any. Stop after approximately self.seconds_of_work_time. """ if self.paused: self.status = self.throbber_paused return while True: # get the first item with a proper load_generator try: item = self.queue[0] if item.load_generator is None: self.queue.popleft() else: break except IndexError: return item.unpause() self.rotate() if item != self.old_item: if self.old_item: self.old_item.pause() self.old_item = item item.unpause() end_time = time() + self.seconds_of_work_time try: while time() < end_time: next(item.load_generator) if item.progressbar_supported: self.fm.ui.status.request_redraw() except StopIteration: self._remove_current_process(item) except Exception as err: self.fm.notify(err) self._remove_current_process(item) def _remove_current_process(self, item): item.load_generator = None self.queue.remove(item) if item.progressbar_supported: self.fm.ui.status.request_redraw() def has_work(self): """Is there anything to load?""" return bool(self.queue) def destroy(self): while self.queue: self.queue.pop().destroy()