Module: Yadriggy::Py
- Defined in:
- lib/yadriggy/py.rb,
lib/yadriggy/py/import.rb,
lib/yadriggy/py/python.rb,
lib/yadriggy/py/codegen.rb,
lib/yadriggy/py/py_typechecker.rb
Overview
Python language embedded in Ruby
Defined Under Namespace
Modules: PyImport Classes: CodeGen, Import, PyTypeChecker
Constant Summary collapse
- Syntax =
Yadriggy.define_syntax do expr = Name | Number | Super | Binary | Unary | ternary | StringLiteral | Lambda | ArrayLiteral | Paren | lambda_call | fun_call | ArrayRef | HashLiteral stmnt = Return | ForLoop | Loop | if_stmnt | Break | BeginEnd | Def | ModuleDef exprs = Exprs | stmnt | expr Name = { name: String } Number = { value: Numeric } VariableCall = Name InstanceVariable = nil GlobalVariable = nil Reserved = Name Const = Name Binary = { left: expr, op: Symbol, right: expr } ArrayRef = { array: expr, indexes: expr } ArrayRefField = ArrayRef Assign = { left: [expr] | expr, op: Symbol, right: [expr] | expr } Dots = Binary Unary = { op: Symbol, operand: expr } StringLiteral = { value: String } ArrayLiteral = { elements: ForLoop | [ expr ] } Paren = { expression: expr } HashLiteral = { pairs: [ (expr|Label|SymbolLiteral) * expr ] } Return = { values: [ expr ] } ForLoop = {vars: [ Identifier ], set: expr, body: exprs } Loop = { op: :while, cond: expr, body: exprs } Break = { values: nil } if_stmnt = Conditional + { op: :if, cond: expr, then: exprs, all_elsif: [expr * exprs], else: (exprs) } ternary = Conditional + { op: :ifop, cond: expr, then: expr, all_elsif: nil, else: expr } Parameters = { params: [ Identifier ], optionals: [ Identifier * expr ], rest_of_params: (Identifier), params_after_rest: [ Identifier ], keywords: [ Label * expr ], rest_of_keywords: (Identifier), block_param: (Identifier) } Block = Parameters + { body: exprs } Lambda = Block + { body: expr } # -> (x) { x + 1 } lambda_name = { name: "lambda" } lambda_call = Call + { receiver: nil, op: nil, name: lambda_name, args: nil, block_arg: nil, block: Block } fun_call = Call + { receiver: (expr), op: (Symbol), name: Identifier, args: [ expr ], block_arg: nil, block: nil } Command = fun_call Exprs = { expressions: [ exprs ] } Rescue = { types: [ Const | ConstPathRef ], parameter: (Identifier), body: (exprs), nested_rescue: (Rescue), else: (exprs), ensure: (exprs) } BeginEnd = { body: exprs, rescue: (Rescue) } Def = Parameters + { singular: (expr), name: Identifier, body: exprs, rescue: (Rescue) } ModuleDef = { name: Const | ConstPathRef, body: exprs, rescue: (Rescue) } ClassDef = ModuleDef + { superclass: (Const | ConstPathRef) } end
Class Method Summary collapse
- .expr_or_subtype(ast) ⇒ Object
- .generate_except_last(ast, gen) ⇒ Object
- .init_free_variables(checker) ⇒ Object
- .run(&blk) ⇒ Object
Class Method Details
.expr_or_subtype(ast) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/yadriggy/py/python.rb', line 117 def self.expr_or_subtype(ast) if ast.nil? || ast.is_a?(Assign) false else usertype = ast.usertype if usertype == :fun_call ast.name.name != 'print' else usertype == :expr || usertype == :lambda_call || usertype == :ternary end end end |
.generate_except_last(ast, gen) ⇒ Object
102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/yadriggy/py/python.rb', line 102 def self.generate_except_last(ast, gen) if expr_or_subtype(ast) ast elsif ast.is_a?(Exprs) && expr_or_subtype(ast.expressions[-1]) ast.expressions[0...-1].each do |e| gen.print(e) gen.newline end ast.expressions[-1] else gen.print(ast) nil end end |
.init_free_variables(checker) ⇒ Object
92 93 94 95 96 97 98 99 100 |
# File 'lib/yadriggy/py/python.rb', line 92 def self.init_free_variables(checker) unless checker.references.empty? gen = CodeGen.new(Printer.new, checker) args = gen.print_free_vars_initializer PyCall.exec(gen.printer.output) f = PyCall.eval(CodeGen::FreeVarInitName) f.call(args) end end |
.run(&blk) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/yadriggy/py/python.rb', line 76 def self.run(&blk) ast = Yadriggy::reify(blk) Syntax.raise_error unless Syntax.check(ast.tree) checker = PyTypeChecker.new checker.typecheck(ast.tree.body) PyCall.exec(Import.source) init_free_variables(checker) gen = CodeGen.new(Printer.new, checker) ast.astrees.each {|t| gen.print(t) unless t == ast } last_expr = generate_except_last(ast.tree.body, gen) PyCall.exec(gen.printer.output) unless last_expr.nil? PyCall.eval(CodeGen.new(Printer.new, checker).print(last_expr).printer.output) end end |