Skip to content

Commit

Permalink
Recovered some lost code, implemented Pointers and struct definition …
Browse files Browse the repository at this point in the history
…backend.
  • Loading branch information
jonashaag committed Jul 8, 2010
1 parent 90bd816 commit b3db60e
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 97 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,2 +1,3 @@
tests/d_parser_mach_*
d_parser_mach*
*.pyc
4 changes: 0 additions & 4 deletions Makefile

This file was deleted.

25 changes: 21 additions & 4 deletions backends/c/__init__.py
Expand Up @@ -13,6 +13,9 @@ def fmt(string, *args, **kwargs):
assert isinstance(value, str), type(value)
return string.format(*args, **kwargs)

def indent_lines(iterator):
return ''.join('\n ' + line for line in iterator)

class CGeneratorBackend(Backend):
fileext = '.c'

Expand All @@ -26,6 +29,7 @@ def translate_ast(self, ast, as_string=True):
try:
for chunk in Backend.translate_ast(self, ast):
self._buf.write(chunk)
self._buf.write('\n')
if as_string:
return self._buf.getvalue()
else:
Expand All @@ -43,13 +47,14 @@ def visit_Identifier(self, node):

def visit_TypeIdentifier(self, node):
name = node.children['name']
return C_BUILTIN_TYPES.get(name, name)
ptr = node.children['pointer'] and '*' or ''
return C_BUILTIN_TYPES.get(name, name) + ptr

def visit_Operator(self, node):
return node.children['op'].symbol

def visit_Integer(self, node):
return node.children['value']
return str(node.children['value'])

visit_Float = visit_Integer

Expand All @@ -62,8 +67,12 @@ def visit_Declaration(self, node):
name=self.visit_node(node.children['name'])
)

def visit_Definition(self, node):
return '%s = %s' % tuple(map(self.visit_node, node.children.itervalues()))

def visit_Block(self, node):
return '{' + '\n'.join(map(self.visit_statement, node.children['statements'])) + '}'
stmts = map(self.visit_statement, node.children['statements'])
return '\n{' + indent_lines(stmts) + '\n}'

def visit_Function(self, node):
header = node.children['header']
Expand All @@ -79,9 +88,11 @@ def visit_Function(self, node):
'return_type' : return_type,
'signature' : ', '.join(signature)
}
return fmt('{return_type} {name}({signature}) {body}', **dct)
return fmt('{return_type} {name}({signature}){body}', **dct)

def visit_Return(self, node):
if not node.children['expr']:
return 'return'
return 'return %s' % self.visit_node(node.children['expr'])

def visit_Call(self, node):
Expand All @@ -94,3 +105,9 @@ def visit_Call(self, node):
def visit_MathExpression(self, node):
return ' '.join(map(str, self.translate_child(node, 'nodes')))

def visit_ObjectTypeDeclaration(self, node):
return 'typedef struct {%s\n} %s;\n' % tuple(
map(self.visit_node, reversed(node.children.values())))

def visit_DeclarationBlock(self, node):
return indent_lines(map(self.visit_statement, node.children['decls']))
32 changes: 17 additions & 15 deletions nodes.py
Expand Up @@ -16,14 +16,17 @@ def __eq__(self, other):
return False
return dict.__eq__(self.children, other.children)

def __repr__(self):
return '<%s %s>' % (
self.__class__.__name__,
'\n'.join('%s:%s' % (k, v) for k, v in self.children.iteritems())
)

class Operator(Node):
def __init__(self, op):
Node.__init__(self)
self.children['op'] = op

def __repr__(self):
return '<Operator \'%s\'>' % self.children['op']

@classmethod
def for_symbol(cls, symbol):
return cls(operators.for_symbol(symbol))
Expand All @@ -38,17 +41,16 @@ def __init__(self, expr):
assert isinstance(expr, Node)
self.children['expression'] = expr

def __repr__(self):
return '(%s)' % self.children['expression']


class Identifier(Expression):
def __init__(self, name):
Expression.__init__(self)
self.children['name'] = name

def __repr__(self):
return '<Identifier %s>' % self.children['name']
class TypeIdentifier(Identifier):
def __init__(self, name, pointer=False):
Identifier.__init__(self, name)
self.children['pointer'] = pointer

class ObjectMember(Expression):
def __init__(self, obj, member):
Expand All @@ -64,9 +66,6 @@ def __init__(self, value):
Expression.__init__(self)
self.children['value'] = value

def __repr__(self):
return '<%s %s>' % (self.__class__.__name__, self.children['value'])

class String(Literal):
pass

Expand Down Expand Up @@ -109,9 +108,6 @@ def __init__(self, *nodes):
Expression.__init__(self)
self.children['nodes'] = list(nodes)

def __repr__(self):
return '<%s %s>' % (self.__class__.__name__, self.children['nodes'])

def merge_list(self, other):
assert isinstance(other, list)
for op, expr in other:
Expand Down Expand Up @@ -174,7 +170,13 @@ class ObjectTypeDeclaration(Statement):
def __init__(self, name, parent_type, decl_block):
Statement.__init__(self)
self.children['name'] = name
self.children['parent_type'] = parent_type
#self.children['parent_type'] = parent_type
# TODO: quickhack
if parent_type.children['name'] != 'Object':
parent_type.children['pointer'] = True
decl_block.children['decls'].insert(0,
Declaration(Identifier('super'), parent_type)
)
self.children['decl_block'] = decl_block

class If(Statement):
Expand Down
15 changes: 11 additions & 4 deletions parser.py
Expand Up @@ -48,12 +48,19 @@ def d_identifier(t):
r''' identifier: "[a-zA-Z_][a-zA-Z0-9_]*" '''
return nodes.Identifier(t[0])

def d_type_identifier(t):
r''' type_identifier: identifier '*'? '''
return nodes.TypeIdentifier(
t[0].children['name'],
len(t[1]) == 1 # 1 = '*' given
)

def d_member(t):
r''' member: identifier '.' identifier '''
return nodes.ObjectMember(t[0], t[2])

def d_declaration(t):
r''' declaration: identifier 'as' identifier '''
r''' declaration: identifier 'as' type_identifier '''
return nodes.Declaration(t[0], t[2])

def d_literal(t):
Expand Down Expand Up @@ -130,7 +137,7 @@ def d_type_declaration(t):
return t[0]

def d_object_type_declaration(t):
''' object_type_declaration: identifier '<-' identifier ':' declaration_block '''
''' object_type_declaration: type_identifier '<-' type_identifier ':' declaration_block '''
return nodes.ObjectTypeDeclaration(t[0], t[2], t[4])

def d_declaration_block(t):
Expand All @@ -146,7 +153,7 @@ def d_function_definition(t):
return nodes.Function(t[0], t[2], t[4])

def d_function_header(t):
''' function_header: 'Function(' signature? ')' ('->' identifier)?'''
''' function_header: 'Function(' signature? ')' ('->' type_identifier)?'''
# very ugly find-out-whether-there-are-signature-and-or-return-type code.
tokens = iter(t)
tokens.next() # pass left parent
Expand Down Expand Up @@ -207,4 +214,4 @@ def d_if_statement(t):
def parse(s, parser=None):
if parser is None:
parser = Parser()
return parser.parse(preprocessor.preprocess(s)).getStructure()
return parser.parse(preprocessor.preprocess(s)).structure
13 changes: 4 additions & 9 deletions snowman.py
Expand Up @@ -33,22 +33,17 @@ def translate_code(*files):
result.write(result_buffer)
else:
# read input from stdin
print backend.translate(parse_code(sys.stdin.read()))
print backend.translate_ast(parse_code(sys.stdin.read()))


if __name__ == '__main__':
def usage(exc):
print >> sys.stderr, 'USAGE: %s (--test | --translate files*)' % exc
args = sys.argv[:]
this_file = args.pop(0)
cmd = 'translate'
if not args:
exit(usage(this_file))

if args[0].startswith('--'):
files = ()
elif args[0].startswith('--'):
cmd = args.pop(0)[2:]
else:
cmd = 'translate'

exit(
{'translate' : translate_code, 'test' : run_tests}[cmd](*args)
)
23 changes: 19 additions & 4 deletions tests/code/test.c
@@ -1,4 +1,19 @@
Int main(Int argc, String argv) {print("Hello, World!");
print("How are you today?");
printf("You gave me '%d' arguments", argc);
return 41 + 1;}
typedef struct {
int* x;
int y;
} Position;

typedef struct {
Position* super;
int z;
} _3DPosition;

int main(int argc, char** argv)
{
print("Hello, World!");
print("How are you today?");
printf("You gave me '%d' arguments", argc);
Position* pos = malloc(sizeof(Position));
_3DPosition* _3dpos = malloc(sizeof(_3DPosition));
return;
}
13 changes: 11 additions & 2 deletions tests/code/test.snow
@@ -1,5 +1,14 @@
main as Function(argc as Int, argv as String) -> Int:
Position <- Object:
x as Int*
y as Int

_3DPosition <- Position:
z as Int

main as Function(argc as Int, argv as String*) -> Int:
print("Hello, World!")
print("How are you today?")
printf("You gave me '%d' arguments", argc)
return 41 + 1
pos as Position* = malloc(sizeof(Position))
_3dpos as _3DPosition* = malloc(sizeof(_3DPosition))
return
2 changes: 1 addition & 1 deletion tests/test.py
Expand Up @@ -2,7 +2,7 @@
import pprint
from itertools import izip

from nodes import Node, Identifier as _, Operator
from nodes import Node, Identifier as _, Operator, TypeIdentifier as _t
from parser import parse

_op = Operator.for_symbol
Expand Down
36 changes: 18 additions & 18 deletions tests/test_function.py
@@ -1,5 +1,5 @@
import unittest
from test import Testcase, _, _op
from test import Testcase, _, _op, _t
from nodes import *

class FunctionTestcase(Testcase):
Expand All @@ -16,14 +16,14 @@ def test_definition(self):
[Function(
_('foo'),
FunctionHeader(
_('String'),
_t('String'),
[
Declaration(_('a'), _('Int')),
Declaration(_('b'), _('Float')),
Declaration(_('c'), _('Bool')),
Declaration(_('d'), _('Bool')),
Declaration(_('e'), _('Bool')),
Declaration(_('f'), _('Bool'))
Declaration(_('a'), _t('Int')),
Declaration(_('b'), _t('Float')),
Declaration(_('c'), _t('Bool')),
Declaration(_('d'), _t('Bool')),
Declaration(_('e'), _t('Bool')),
Declaration(_('f'), _t('Bool'))
]
),
Block([
Expand All @@ -48,10 +48,10 @@ def test_definition(self):

def test_recursion(self):
self.assert_generates_ast('''
bear as Function(emma as Heifer, bertram as Bull) -> Calf:
return new(Calf)
bear as Function(emma as Heifer*, bertram as Bull*) -> Calf*:
return malloc(sizeof(Calf))
bear_n as Function(n as Int, emma as Heifer, bertram as Bull):
bear_n as Function(n as Int, emma as Heifer*, bertram as Bull*):
if not n:
return
else:
Expand All @@ -62,22 +62,22 @@ def test_recursion(self):
Function(
_('bear'),
FunctionHeader(
_('Calf'),
_t('Calf', True),
[
Declaration(_('emma'), _('Heifer')),
Declaration(_('bertram'), _('Bull'))
Declaration(_('emma'), _t('Heifer', True)),
Declaration(_('bertram'), _t('Bull', True))
],
),
Block([Return(Call(_('new'), [_('Calf')]))])
Block([Return(Call(_('malloc'), [Call(_('sizeof'), [_('Calf')])]))])
),
Function(
_('bear_n'),
FunctionHeader(
None,
[
Declaration(_('n'), _('Int')),
Declaration(_('emma'), _('Heifer')),
Declaration(_('bertram'), _('Bull'))
Declaration(_('n'), _t('Int')),
Declaration(_('emma'), _t('Heifer', True)),
Declaration(_('bertram'), _t('Bull', True))
],
),
Block([
Expand Down
10 changes: 5 additions & 5 deletions tests/test_maths.py
@@ -1,5 +1,5 @@
import unittest
from test import Testcase, _, _op
from test import Testcase, _, _op, _t
from nodes import *

class MathsTestCase(Testcase):
Expand All @@ -14,11 +14,11 @@ def test_multiple(self):
''',
[
Definition(
Declaration(_('a'), _('Int')),
Declaration(_('a'), _t('Int')),
MathExpression(Integer(5), _op('*'), Integer(8)),
),
Definition(
Declaration(_('b'), _('Float')),
Declaration(_('b'), _t('Float')),
MathExpression(Integer(10), _op('*'), Float(3.14))
),
Assignment(_('b'),
Expand Down Expand Up @@ -76,11 +76,11 @@ def test_with_vars_and_calls(self):
''',
[
Definition(
Declaration(_('a'), _('Int')),
Declaration(_('a'), _t('Int')),
MathExpression(Integer(5), _op('**'), Float(0.7))
),
Definition(
Declaration(_('b'), _('Float')),
Declaration(_('b'), _t('Float')),
MathExpression(
Float(0.2),
_op('*'),
Expand Down

0 comments on commit b3db60e

Please sign in to comment.