Skip to content

Commit

Permalink
pass c# and c++ syntax tests
Browse files Browse the repository at this point in the history
  • Loading branch information
alehander92 committed Mar 5, 2016
1 parent 6d27d23 commit 0b0cf89
Show file tree
Hide file tree
Showing 35 changed files with 1,275 additions and 412 deletions.
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ or in pseudon AST format and we can translate to any of the supported target lan

## progress

close to v0.2, several fixes and finishing the api only left

- [ ] python
- [x] syntax tests passing
- [ ] api tests passing
Expand All @@ -51,13 +53,13 @@ or in pseudon AST format and we can translate to any of the supported target lan
- [x] syntax tests passing
- [ ] api tests passing
- [ ] c#
- [ ] syntax tests passing
- [x] syntax tests passing
- [ ] api tests passing
- [ ] c++
- [ ] syntax tests passing
- [x] syntax tests passing
- [ ] api tests passing
- [ ] go
- [ ] syntax tests passing
- [x] syntax tests passing
- [ ] api tests passing
- [ ] php
- [ ] syntax tests passing
Expand All @@ -74,7 +76,7 @@ or in pseudon AST format and we can translate to any of the supported target lan
- [x] go
- [ ] php

next version:
v0.3/v0.4:

- [ ] java
- [ ] perl
Expand All @@ -83,6 +85,7 @@ next version:
- [ ] c ?

- [ ] clojure ?

## Language support

Using pseudon's DSL it's really easy to add support for a new language, so soon we'll try to support
Expand Down
7 changes: 5 additions & 2 deletions examples/f.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import "fmt"
class ExError : Exception



func main() {
fmt.Println(2)
throw ExError("s")
}
10 changes: 5 additions & 5 deletions examples/f.pseudo.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
constants: []
custom_exceptions:
- {base: null, name: ExError, type: custom_exception}
definitions: []
dependencies: []
main:
- args:
- {pseudo_type: Int, type: int, value: 2}
function: display
namespace: io
- exception: ExError
pseudo_type: Void
type: standard_call
type: throw_statement
value: {pseudo_type: String, type: string, value: s}
type: module
15 changes: 3 additions & 12 deletions examples/f.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
def f(s):
return s(2)

class A:
def expand(self, a):
return B(a)


class B:
def __init__(self, a):
self.a = a

class ExError(Exception):
pass

raise ExError('s')
11 changes: 2 additions & 9 deletions examples/f.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
def f
''
class ExError < StandardError
end

puts f
begin
2
f
rescue StandardError => e
puts e
end

throw ExError.new('s')

54 changes: 37 additions & 17 deletions pseudon/api_translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from pseudon.api_handlers import LeakingNode, NormalLeakingNode, BizarreLeakingNode
import copy

TYPES = {'List', 'Dictionary', 'Set', 'Tuple', 'Regexp', 'Array', 'String'}

def to_op(op, reversed=False):
'''
create a function that transforms a method to a binary op
Expand Down Expand Up @@ -83,7 +85,10 @@ def api_translate(self):
for l in self.used:
m = self.dependencies.get(l, {}).get('@all')
if m:
self.standard_dependencies.add(m)
if isinstance(m, list):
self.standard_dependencies |= set(m)
else:
self.standard_dependencies.add(m)

transformed.dependencies = [
Node('dependency', name=name) for name in self.standard_dependencies]
Expand All @@ -93,16 +98,23 @@ def api_translate(self):
def after(self, node, in_block, assignment):
if node and not isinstance(node, Node):
return node
if node and node.type in {'list', 'dictionary', 'set', 'tuple', 'regexp', 'array'}:
self.used.add(node.type.title())
elif node and node.type == 'assignment':
if node.value and isinstance(node.value.pseudo_type, list) and node.value.pseudo_type[0] in {'List', 'Dictionary', 'Set', 'Tuple', 'Regexp', 'Array'}:
self.used.add(node.value.pseudo_type[0])
if node:
if node.type.title() in TYPES:
self.used.add(node.type.title())
# elif isinstance(node, list) and node.type[0] in TYPES:
# self.used.add(node.type[0].title())
if node and (node.type == 'try_statement' or node.type == 'throw_statement'):
self.used.add('Exception')
if node and node.type == 'assignment' and node.value:
self.update_used(node.value.pseudo_type)

if node and node.type == 'assignment' and node.value and node.value.type == 'binary_op':
if node.value.right == node.target:
node = Node('operation_assign', slot=node.value.left, op=node.value.op, value=node.value.right)

if node and hasattr(node, 'params'):
self.update_used(node.pseudo_type)

if node and node.type == 'call':
if node.function.type == 'attr' and node.function.object.type == 'local' and hasattr(self, 'js_dependencies') and node.function.object.name in self.js_dependencies:
self.standard_dependencies.add(self.js_dependencies[node.function.object.name])
Expand Down Expand Up @@ -159,7 +171,9 @@ def leaking(self, z, module, name, node, context, *data):
c++ guys, stay calm
'''

z = z(module, name, node.args)
# input(node.y)
args = [node.receiver] + node.args if node.type == 'standard_method_call' else node.args
z = z(module, name, args)
if context == 'expression':
if isinstance(z, NormalLeakingNode):
leaked_nodes, exp = z.as_expression()
Expand Down Expand Up @@ -211,17 +225,11 @@ def transform_standard_call(self, node, in_block=False, assignment=None):
return result

def update_dependencies(self, namespace, function, arg_types):
if namespace == 'List':
self.used_list = True
elif namespace == 'Dictionary':
self.used_dictionary = True
if namespace in TYPES:
self.used.add(namespace)

for a in arg_types:
if isinstance(a, list):
if a[0] == 'List':
self.used_list = True
elif a[0] == 'Dictionary':
self.used_dictionary = True
self.update_used(a)

if namespace not in self.dependencies:
return
Expand Down Expand Up @@ -279,7 +287,7 @@ def _expand_api(self, api, receiver, args, pseudo_type, equivalent):
def _parse_part(self, part, receiver, args, equivalent):
if part[0] == '%': # %{v}
inside = part[2:-1]
if inside.isnum():
if inside.isnumeric():
inside = int(inside)
return args[inside]
elif inside == 'self':
Expand All @@ -294,3 +302,15 @@ def _parse_part(self, part, receiver, args, equivalent):
return getattr(self, '%s_placeholder' % inside)(receiver, *args, equivalent=equivalent)
else:
return local(part)

def update_used(self, t):
if isinstance(t, list):
for type_ in t:
if isinstance(type_, str):
if type_ in TYPES:
self.used.add(type_)
else:
self.update_used(type_)
else:
if t in TYPES:
self.used.add(t)
99 changes: 99 additions & 0 deletions pseudon/api_translators/cpp_api_handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
from pseudon.pseudon_tree import Node, call, method_call, local, assignment, to_node
from pseudon.api_handlers import BizarreLeakingNode, NormalLeakingNode

class Read(BizarreLeakingNode):
'''
transforms `io:read`
`a = io:read()`
`cin << a`
'''

def temp_name(self, target):
return '_read_result'

def as_expression(self):
return [
Node('_cpp_declaration',
name='_dummy',
args=[],
decl_type='String',
pseudo_type='Void'),
Node('_cpp_cin',
args=[local('_dummy', 'String')])
], None

def as_assignment(self, target):
return [Node('_cpp_cin', args=[target])]

class Slice(BizarreLeakingNode):
'''
transforms `List:slice..`
'''

def temp_name(self, target):
return '_sliced'

def as_expression(self):
# pseudo_type=self.args[0].pseudo_type
begin = method_call(self.args[0], 'begin', [], 'CppIterator')
end = method_call(self.args[0], 'end', [], 'CppIterator')
if self.name == 'slice_to':
from_, to = to_node(0), self.args[1]
else:
from_, to = self.args[1], self.args[2]
if from_.type == 'int' and from_.value == 0:
start = begin
else:
start = Node('binary_op', op='+', left=begin, right=from_, pseudo_type='CppIterator')
if self.name == 'slice_from':
finish = end
elif to.type == 'int' and to.value < 0:
finish = Node('binary_op', op='-', left=end, right=to_node(-to.value))
else:
finish = Node('binary_op', op='+', left=begin, right=to, pseudo_type='CppIterator')
return [
Node('_cpp_declaration',
name='_sliced',
args=[start, finish],
decl_type=self.args[0].pseudo_type,
pseudo_type='Void')], None

def as_assignment(self, target):
expression = self.as_expression()[0][0]
expression.name = target.name
return [expression]

class ReadFile(BizarreLeakingNode):
'''
transforms `io:read_file`
'''

def temp_name(self, target):
return '_file_contents'

def as_expression(self):
return [Node('_cpp_declaration',
name='ifs',
args=[to_node('f.py')],
decl_type='ifstream',
pseudo_type='Void'),
Node('_cpp_declaration',
name=self.temp_name(None),
args=[Node('_cpp_group',
value=Node('_cpp_anon_declaration',
args=[local('ifs', 'ifstream')],
decl_type='istreambuf_iterator<char>',
pseudo_type='Void')),
Node('_cpp_group',
value=Node('_cpp_anon_declaration',
args=[],
decl_type='istreambuf_iterator<char>',
pseudo_type='Void'))],
decl_type='String',
pseudo_type='Void')], None

def as_assignment(self, target):
e = self.as_expression()[0]
e[1].name = target.name
return e
Loading

0 comments on commit 0b0cf89

Please sign in to comment.