# coding=utf-8 import operator import prolog.engine from server.hints import Hint, HintPopup id = 1 hint_type = { 'no_hint': Hint('no_hint'), 'program_already_correct': Hint('program_already_correct'), 'system_error': Hint('system_error'), 'test_results': Hint('test_results'), 'syntax_error': Hint('syntax_error'), 'monkey_main': Hint('monkey_main'), 'monkey_change': HintPopup('monkey_change', style='change'), 'monkey_insert': HintPopup('monkey_insert', style='insert'), 'monkey_remove': HintPopup('monkey_remove', style='remove'), 'noncapitalised_variable': Hint('noncapitalised_variable'), 'noncapitalised_variable_markup': HintPopup('noncapitalised_variable_markup'), } def hint(code, aux_code): try: engine_id, output = prolog.engine.create(code=code+aux_code, timeout=1.0) # Check program for syntax errors. if 'error' in map(operator.itemgetter(0), output): errors_msg = '\n'.join(['{}: {}'.format(m_type, m_text) for m_type, m_text in output]) return [{'id': 'syntax_error', 'args': {'messages': errors_msg}}] tokens = prolog.util.tokenize(code) # a,b,c are a bit dangerous when crossing the river exercise is being solved # what about potential numbers after letters? # this will have to be solved more generally targets = [prolog.util.Token('NAME', 'x'), prolog.util.Token('NAME', 'y'), prolog.util.Token('NAME', 'z'), prolog.util.Token('NAME', 'a'), prolog.util.Token('NAME', 'b'), prolog.util.Token('NAME', 'c')] marks = [(t.pos, t.pos + len(t.val)) for t in tokens if t in targets] if marks: return [{'id': 'noncapitalised_variable_markup', 'start': m[0], 'end': m[1]} for m in marks] + \ [{'id': 'noncapitalised_variable'}] except socket.timeout as ex: pass finally: if engine_id is not None: prolog.engine.destroy(engine_id) return []