ideen fuer mein 'pyclet'?

Du hast eine Idee für ein Projekt?
Antworten
Costi
User
Beiträge: 544
Registriert: Donnerstag 17. August 2006, 14:21

Samstag 3. März 2007, 03:37

tach allerseits

ich sitz hier schon ein paar stuendchen zuviel, und ,machs kurz:
und zwar gehts darum python code kuerzer und moechlichst einfacher zu machen als es ist und noch ein par andere coole extras einzubauen


hier ein beispiel.
dies:

Code: Alles auswählen

[cmt ein constructor
(constr helo dummy
[return [str print [str helo wrongfull world
)
[helo 


[cmt methoden
(def test arg
(if [inln arg == 0
[return [str freibier]
)
)
[set bar [test 0
[print bar


[cmt listen...
[set z [list 1 3 5 7 9
print [get z -1

[cmt netter nebeneffekt
([obj sys stdout write] (str helo splited wor
ld))
wuerde zu

Code: Alles auswählen

# ein constructor

print "helo wrongfull world"

# methoden
def test(arg):
 if arg == 0:
  return "freibier"
  
  
 
bar = test(0)
print bar

# listen...
z = [1, 3, 5, 7, 9]
print z[-1]
# netter nebeneffekt
sys.stdout.write("""helo splited wor
ld""")
ueberstezt



irgendwelch ideen was man da noch einbauen koennte (fuer nachdem ich alles ordentlich endbugt habe)


gruesse
costi





Code: Alles auswählen

import re
import sys

class Pygen:
	def __init__(self):
		pass

		
	#if else, elif, ...
	def def_(self, arg):
		head, code = arg.split('\n', 1)
		code = '\n' + code #damit korrekt indendet werden kann
		if ' ' in head:
			name, arg = head.split(' ', 1)
		else:
			name = head
			arg = ''
		arg = arg.replace(' ', ', ')
		return 'def %s(%s):%s\n<end>' % (name, arg, code)
	def if_(self, arg):
		condition, code = arg.split('\n', 1)
		code = '\n' + code
		retval = ''
		for line in code.split('\n'):
			if 'else' == line:
				line = '<end>\nelse:'
			if line.split(' ', 1)[0] == 'elif':
				cond = ''.join(line.split(' ', 1)[1:])
				line = '<end>\nelif %s:' % cond
			retval += line + '\n'
		return 'if %s:%s\n<end>' % (condition, retval)
	def while_(self, arg):
		cond, code = arg.split('\n', 1)
		return "while %s:\n%s\n<end>" % (cond, code)
	def for_(self, arg):
		head, code = arg.split('\n', 1)
		var, cond = head.split(' ', 1)
		return 'for %s in %s:\n%s\n<end>' % (var, cond, code)
	def class_def (self, arg):
		return self.def_("self %s" % arg)
	
	
	#other python syntax things
	def list(self, arg):
		elements = arg.replace(' ', ', ')
		return ('{%s}') % elements
	def set(self, arg): #q w - e r -> q, w = e, r ; q w e -> q, w = y
		if ' - ' in arg:
			var, val = arg.split(' - ')
		else:
			arg = arg.split(' ')
			val = arg[-1]
			var = ''.join(arg[:-1])
		var = var.replace(' ', ', ')
		val = val.replace(' ', ', ')
		return '%s = %s' % (var, val)
	def call(self, arg):
		if ' ' in arg:
			method, args = arg.split(' ', 1)
			args = args.replace(' ', ', ')
		else:
			method = arg
			args = ''
		if method in ['print', 'return']:
			return '%s %s' % (method, args)
		return '%s(%s)' % (method, args)
	def obj(self, arg):
		return arg.replace(' ', '.')
	def get(self, arg):
		var, index = arg.split(' ')
		return '%s{%s}' % (var, index)
	def str(self, arg):
		parentis = '"'
		if '\n' in arg:
			parentis = '"""'
			if '"""' in arg:
				if "'''" in arg:
					print "str: error blabla"
					sys.exit()
				parentis = "'''"
		else:
			parentis = '"'
			if '"' in arg:
				if "'" in arg:
					print "str: error blabalabala"
					sys.exit()
				parentis = "'"
		return '%s%s%s' % (parentis, arg, parentis)
			
	
	#etc
	def import_(self, arg):
		return arg
	def cmt(self, arg):
		return '# %s' % arg
	def nix(self, dummy):
		return ''
	def inln(self, arg):
		return arg
	def magic(self, arg):
		code = arg.replace('@', ' ')

		# weil exec pingelig ist
		code = re.sub('^[\n ]*', '', code)
		code = re.sub('[\n ]*$', '', code)
		
		code = indent(code)
		exec(code)
		return ''
	def constr(self, arg):
		if '\n' in arg:
			def_name = arg.split(' ', 1)[0]
			code = self.def_(arg)
			print (code + '\nself.%s = %s' % (def_name, def_name))
			self.magic(code + '\nself.%s = %s' % (def_name, def_name))
		else:
			var, value = arg.split(' ')
			exec('self.%s = %s' % (var, value))
		
		return ''
		
		
			
	
	
	
	
	
	#=======================================================



def syntax_error(msg):
	print 'syntax error:'
	print msg
	sys.exit()

def replace(stri, begin, end, sub):
	return stri[0:begin] + sub + stri[end+1:-1]

def complete(arg, obj):
	for attr in dir(obj):
		if attr.endswith('_'):
			if attr[:-1] == arg:
				return attr
		else:
			if attr == arg:
				return arg
def indent(programm, indentation = ' '):
	level = 0
	prog = ''
	for line in programm.split('\n'):
		if line.endswith(":"): #spater dan nochmal regex ersetzen
			prog += level*indentation + line + '\n'
			level += 1
		elif line == '<end>':
			level -= 1
		else:
			prog += level*indentation + line + '\n'
	
	return prog

#ergaenzt triviale ]s
def abk(code):
	retval = ''
	for line in code.split('\n'):
		z = line.count('[') - line.count(']')
		if z > 0:
			retval += line + z*']' + '\n'
		else:
			retval += line + '\n'
	return retval

def compile(programm):
	programm = re.sub('\n\s?\[', '\n[', programm)
	programm = '\n%s%s\n%s' % (' '*12, programm, ' '*12) #ich verstehe auch nicht richtig, warum man ein paar chars luftraum braucht
	#fehlende ] addieren
	programm = abk(programm)

	programm = programm.replace('(', '[').replace(')', ']')
	p = Pygen()
	found = 0
	
	found_cmd = True # a cmd is sth in []

	while found_cmd:
		found_cmd = False
		counter = 0
		for char in programm:
			if char == '[':
				found = counter
			elif char == ']':
				if found:
					found_cmd = True
					cmd = programm[found+1:counter]
					method_incomplete, arg = cmd.split(' ', 1)
					method = complete(method_incomplete, p)
					print [method], 'got', [arg], 'as argument'
					if not method:
						method = "call"
						arg = cmd
					py_cmd = getattr(p, method)(arg)
					
					#think this like escaping ' '
					py_cmd = py_cmd.replace(' ', '@')
					
					programm = replace(programm, found, counter, py_cmd)
					print 'and returned', [py_cmd.replace('@', ' ')]
					#print programm.replace('@', ' ')
					found = 0
					
					# etwas in [] wurde gefunden, durch python code ertsetz und ' 's escaped. Also dies aufs neue bis nichts mehr in [] gefunden wird (found_cmd = False)
					break
					
			counter += 1
	
	programm = re.sub('^[\n\s]*', '', programm)
	programm = re.sub('[\n\s]*$', '', programm)
	programm = programm.replace('@', ' ').replace('}', ']').replace('{', '[')
	programm = indent(programm)	
	return programm

def run(code):
	c = compile(code)
	print '========================'
	print '------------------------'
	print c
	exec(c)
	return c

print '===================='
print '////////////////////'



f = file('pyclet.txt', 'w')
f.write(run("""

[cmt ein constructor
(constr helo dummy
[return [str print [str helo wrongfull world
)
[helo 


[cmt methoden
(def test arg
(if [inln arg == 0
[return [str freibier]
)
)
[set bar [test 0
[print bar


[cmt listen...
[set z [list 1 3 5 7 9
print [get z -1

[cmt netter nebeneffekt
([obj sys stdout write] (str helo splited wor
ld))













"""))








[/code]
cp != mv
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Samstag 3. März 2007, 08:59

Du solltest dir mal Lisp ansehen.
TUFKAB – the user formerly known as blackbird
BlackJack

Samstag 3. März 2007, 10:52

Oder Scheme oder Noodle wenn's was mit Python zu tun haben soll. Hier Dein Beispiel in Noodle:

Code: Alles auswählen

(import sys)

# Ein Kommentar
(comment Noch ein Kommentar)

(print "helo wrongfull world")

(define (test arg)
    (when (== arg 0) "freibier"))

(= bar (test 0))
(print bar)

(= z \[1 3 5 7 9])
(print [z -1])

(.sys.stdout.write """helo splited wor
ld""")
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Samstag 3. März 2007, 11:03

Costi hat geschrieben:und zwar gehts darum python code kuerzer und moechlichst einfacher zu machen als es ist
Tut mir leid, aber daran bist du total gescheitert - pycle ist um ein vielfaches komplizierter. Vorteile hat es so wie ich sehe keine - wenn es wenigstens in einen performanten Code kompiliert werden könnte (C) der von Python als Modul importiert werden könnte, ala Pyrex. Aber so ist es ein Codegenerator der aus einer esoterischen Programmiersprache eine normale kompiliert.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Costi
User
Beiträge: 544
Registriert: Donnerstag 17. August 2006, 14:21

Samstag 3. März 2007, 12:13

Tut mir leid, aber daran bist du total gescheitert - pycle ist um ein vielfaches komplizierter. Vorteile hat es so wie ich sehe keine
sehe ich leider auch so, deswegen brauche ich frische ideen :lol: :lol:
(und verdammt der grundaufbau von noodle ist ja praktisch genau wie der von pyclet - gibt es den noch irgendwas was noch nicht geschrieben wurde?)
cp != mv
BlackJack

Samstag 3. März 2007, 12:43

Noodle ist schon eher eine echte eigenständige Sprache als ein einfacher Übersetzer nach Python. Noodle wird direkt in Python-Bytecode übersetzt. Ausserdem gibt's Makros, ein Sprachkonstrukt was es in Python (mit Absicht) nicht gibt.
Antworten