Kill everything
This commit is contained in:
parent
bfef42cc66
commit
f5836da2a5
11
AUTHORS
11
AUTHORS
@ -1,11 +0,0 @@
|
||||
Code contributors:
|
||||
|
||||
- Paul R. Tagliamonte <tag@pault.ag>
|
||||
- Gergely Nagy <algernon@madhouse-project.org>
|
||||
|
||||
I'd also like to thank the following people:
|
||||
|
||||
- Kragen Sitaker:
|
||||
Major thanks goes to Kragen on helping me work through some of the
|
||||
initial namespacing crap with the first (really functional) attempt
|
||||
at solving the problem.
|
19
COPYRIGHT
19
COPYRIGHT
@ -1,19 +0,0 @@
|
||||
Copyright (c) 2010-2012 Paul Tagliamonte <tag@pault.ag>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
4
REFACTOR
4
REFACTOR
@ -1,4 +0,0 @@
|
||||
|
||||
overhaul state stuff, machine stuff, revise to be smart
|
||||
|
||||
generate ast in a better way; use "prims" & macros to compile hy
|
@ -1,9 +0,0 @@
|
||||
#!/bin/sh
|
||||
"""":
|
||||
exec /usr/bin/env bpython -i $0 $@
|
||||
"""
|
||||
|
||||
import hy.lang.importer
|
||||
import sys
|
||||
|
||||
print "Hython is now importable!"
|
28
bin/hython
28
bin/hython
@ -1,28 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
from hy.lang.importer import _hy_import_file
|
||||
|
||||
from code import InteractiveConsole
|
||||
import traceback
|
||||
import sys
|
||||
|
||||
try:
|
||||
import readline
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
sys.argv = sys.argv[1:]
|
||||
mod = _hy_import_file(sys.argv[0], '__main__')
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
InteractiveConsole().interact(banner="""
|
||||
"Really, if the lower orders don’t set us a good example, what on
|
||||
earth is the use of them?"
|
||||
|
||||
-- Oscar Wilde (The Importance of Being Earnest)
|
||||
|
||||
|
||||
The hython bits have been loaded -- magically, .hy
|
||||
files are importable!""")
|
1
demo/.gitignore
vendored
1
demo/.gitignore
vendored
@ -1 +0,0 @@
|
||||
static/css
|
@ -1,14 +0,0 @@
|
||||
LESSC = lessc
|
||||
LESSCFLAGS = -x
|
||||
DEPLOYMENT = dev
|
||||
|
||||
all: clean build
|
||||
|
||||
STATIC=./static
|
||||
|
||||
clean:
|
||||
rm -rf $(STATIC)/css
|
||||
|
||||
build:
|
||||
mkdir $(STATIC)/css
|
||||
$(LESSC) $(LESSCFLAGS) less/debuild.me.less > $(STATIC)/css/debuild.css
|
27
demo/app.py
27
demo/app.py
@ -1,27 +0,0 @@
|
||||
from hy.compiler.ast27 import forge_ast
|
||||
from hy.lex.tokenize import tokenize
|
||||
import codegen
|
||||
|
||||
from flask import Flask, render_template, request
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
|
||||
@app.route('/translate', methods=['POST'])
|
||||
def translate():
|
||||
lines = request.form['code']
|
||||
|
||||
try:
|
||||
code = tokenize(lines)
|
||||
ast = forge_ast("stdin", code)
|
||||
return codegen.to_source(ast)
|
||||
except Exception as e:
|
||||
return str(e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
@ -1,12 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
last=""
|
||||
while [ true ]; do
|
||||
now=$(find ./less -type f -printf "%T@ %Tx %TX %p\n" | sort -n -r | head -1)
|
||||
if [ "$last" != "$now" ]; then
|
||||
make >/dev/null
|
||||
echo "Updated."
|
||||
fi
|
||||
last=$now
|
||||
sleep 1
|
||||
done
|
@ -1,16 +0,0 @@
|
||||
@background-color: #DCDCDC;
|
||||
@color: #333333;
|
||||
|
||||
@link-color: #191921;
|
||||
|
||||
@nav-background-color: #333333;
|
||||
@nav-color: #EEEEEE;
|
||||
@nav-border: #FFFFFF;
|
||||
@nav-height: 50px;
|
||||
|
||||
@shadow-color: #333333;
|
||||
|
||||
@nav-from: #CACACA;
|
||||
@nav-to: #F5F5F5;
|
||||
|
||||
@table-zebra: #FFFFFF;
|
@ -1,6 +0,0 @@
|
||||
@import "config.less";
|
||||
|
||||
@import "macros.less";
|
||||
@import "font.less";
|
||||
|
||||
@import "layout.less";
|
@ -1,32 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'Damion';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Damion'), url(../fonts/Damion.woff) format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Cantarel';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(../fonts/cantarell.otf);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Quicksand';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Quicksand'), url(../fonts/Quicksand.woff) format('woff');
|
||||
}
|
||||
|
||||
.damion {
|
||||
font-family: 'Damion', cursive;
|
||||
}
|
||||
|
||||
.quicksand {
|
||||
font-family: 'Quicksand', sans-serif;
|
||||
}
|
||||
|
||||
.cantarell {
|
||||
font-family: 'Cantarel', sans-serif;
|
||||
}
|
@ -1,146 +0,0 @@
|
||||
.noshim {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
html, body {
|
||||
background-color: @background-color;
|
||||
background-image: url(../imgs/texture.png);
|
||||
height: 100%;
|
||||
.noshim;
|
||||
.cantarell;
|
||||
}
|
||||
|
||||
pre {
|
||||
border-radius: 5px;
|
||||
background-color: #FFFFFF;
|
||||
padding: 10px;
|
||||
border: 1px solid darken(@background-color, 1%);
|
||||
}
|
||||
|
||||
.spacer {
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: @link-color;
|
||||
}
|
||||
|
||||
ul {
|
||||
.noshim;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
.noshim;
|
||||
border-spacing: 0px;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid darken(@background-color, 1%);
|
||||
tr {
|
||||
.noshim;
|
||||
td {
|
||||
.noshim;
|
||||
padding: 5px;
|
||||
}
|
||||
border-bottom: 1px solid darken(@background-color, 1%);
|
||||
}
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
table.zebra {
|
||||
tr:nth-child(2n) {
|
||||
background-color: @table-zebra;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.content {
|
||||
background-color: #F8F8F8;
|
||||
min-height: 70%;
|
||||
border-bottom: 1px solid #888888;
|
||||
padding-top: 30px;
|
||||
}
|
||||
|
||||
.container {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 700px;
|
||||
}
|
||||
|
||||
.main-container {
|
||||
.container;
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
|
||||
.shim {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.header {
|
||||
.color {
|
||||
width: 12.5%;
|
||||
height: 10px;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.shadow {
|
||||
box-shadow: 5px 5px rgba(15,15,15,0.05);
|
||||
}
|
||||
|
||||
|
||||
.popover {
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
.focus {
|
||||
.shadow;
|
||||
border: 1px solid #CCCCCC;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 5px;
|
||||
width: 90%;
|
||||
height: 85%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 5%;
|
||||
}
|
||||
}
|
||||
|
||||
#repl-input {
|
||||
border-right: 1px solid #DDDDDD;
|
||||
}
|
||||
|
||||
.repl {
|
||||
height: 100%;
|
||||
padding: 3px;
|
||||
.repl-left {
|
||||
float: left;
|
||||
}
|
||||
.repl-right {
|
||||
float: right;
|
||||
}
|
||||
.repl-pane {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
border: 0px solid #000000;
|
||||
resize: none;
|
||||
width: 48%;
|
||||
height: 99%;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 0.5em;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
.box-shadow(@style) {
|
||||
box-shadow: @style @shadow-color;
|
||||
-webkit-box-shadow: @style @shadow-color;
|
||||
-moz-box-shadow: @style @shadow-color;
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 170 B |
2
demo/static/jquery-1.8.3.min.js
vendored
2
demo/static/jquery-1.8.3.min.js
vendored
File diff suppressed because one or more lines are too long
1
demo/static/jquery.min.js
vendored
1
demo/static/jquery.min.js
vendored
@ -1 +0,0 @@
|
||||
jquery-1.8.3.min.js
|
@ -1,64 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{% block title %}{% endblock %} | hy</title>
|
||||
<link rel = "stylesheet" href = "{{ url_for('static', filename='css/debuild.css') }}" ></link>
|
||||
<script src = '{{ url_for('static', filename='jquery.min.js') }}' ></script>
|
||||
<script type="text/javascript">
|
||||
function reload() {
|
||||
var input = $("#repl-input").val();
|
||||
console.log("Input: " + input);
|
||||
$('#repl-output').load(
|
||||
'/translate',
|
||||
{"code": input}
|
||||
);
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
var count = 0;
|
||||
$("#repl-input").keyup(function(e) {
|
||||
var curcount;
|
||||
count = count + 1;
|
||||
curcount = count;
|
||||
|
||||
window.setTimeout(
|
||||
function() {
|
||||
if ( curcount == count ) {
|
||||
reload();
|
||||
} else {
|
||||
/* Pass. User is still typing */
|
||||
}
|
||||
},
|
||||
500
|
||||
);
|
||||
});
|
||||
reload();
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id = 'popshim' >
|
||||
<div class = 'popover' >
|
||||
<div class = 'focus' >
|
||||
<div class = 'repl' >
|
||||
<textarea id = 'repl-input' class = 'repl-pane repl-left' >
|
||||
(defn square [x]
|
||||
(* x x))
|
||||
|
||||
(print (square 4))
|
||||
</textarea>
|
||||
<pre
|
||||
id = 'repl-output'
|
||||
class = 'repl-pane repl-right'
|
||||
></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class = 'logo' >
|
||||
<img src = '{{ url_for('static', filename='imgs/logo.png') }}' alt = 'hython' />
|
||||
</div>
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
@ -1,6 +0,0 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Welcome!{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% endblock %}
|
@ -1,13 +0,0 @@
|
||||
; Copyright (c) Paul R. Tagliamonte <tag@pault.ag>, 2013 under the terms of
|
||||
; hy.
|
||||
|
||||
(import-from flask
|
||||
Flask render-template)
|
||||
|
||||
|
||||
(def app (Flask "__main__"))
|
||||
|
||||
|
||||
(decorate-with (.route app "/")
|
||||
(defn index []
|
||||
(render-template "index.html")))
|
@ -1,5 +0,0 @@
|
||||
import hy.lang.importer # NOQA
|
||||
from app import app
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
@ -1 +0,0 @@
|
||||
<h1>It works!</h1>
|
@ -1,9 +0,0 @@
|
||||
; vim: tabstop=2 expandtab shiftwidth=2 softtabstop=2 filetype=lisp
|
||||
; Copyright (c) Paul Tagliamonte, in sofar as any of this is at all
|
||||
; copyrightable.
|
||||
|
||||
(import "sunlight")
|
||||
|
||||
|
||||
(for [x (kwapply (sunlight.openstates.legislators) {"state" "ma"})]
|
||||
(print (index x "first_name")))
|
@ -1,35 +0,0 @@
|
||||
(import sys) ; for arguments
|
||||
(import-from sh apt-cache) ; for apt-cache
|
||||
|
||||
|
||||
(def package "fluxbox")
|
||||
(if (> (len sys.argv) 1)
|
||||
(def package (index sys.argv 1)))
|
||||
|
||||
|
||||
(defn parse-rfc-822 [inpu]
|
||||
(do (def keys {})
|
||||
(def key None)
|
||||
(def val None)
|
||||
(for [x (.splitlines inpu)]
|
||||
(if (!= x "")
|
||||
(if (!= (index x 0) " ")
|
||||
(do (def kv (.split x ":" 1))
|
||||
(def key (.strip (index kv 0)))
|
||||
(set-index keys key (.strip (index kv 1))))
|
||||
(do
|
||||
(if (== x " .")
|
||||
(def x ""))
|
||||
(set-index keys key (+ (index keys key) "\n" (.strip x)))))))
|
||||
(dict keys)))
|
||||
|
||||
|
||||
(defn get-info [package]
|
||||
(parse-rfc-822 (.show apt-cache package)))
|
||||
|
||||
|
||||
(def data (get-info package))
|
||||
|
||||
(print "The maintainer for" package "is" (index data "Maintainer"))
|
||||
(print "")
|
||||
(print package "is a(n)" (index data "Description-en"))
|
47
grammar.md
47
grammar.md
@ -1,47 +0,0 @@
|
||||
## Lexical syntax ##
|
||||
|
||||
OPEN-PAREN := '('
|
||||
|
||||
CLOSE-PAREN := ')'
|
||||
|
||||
OPEN-SQUARE := '['
|
||||
|
||||
CLOSE-SQUARE := ']'
|
||||
|
||||
OPEN-CURLY := '{'
|
||||
|
||||
CLOSE-CURLY := '}'
|
||||
|
||||
WHITESPACE := ' ' | '\t' | '\n' | '\r'
|
||||
|
||||
COMMENT := ';' ???
|
||||
|
||||
STRING := '"' ??? '"'
|
||||
|
||||
CONSTANT := '*' ??? '*'
|
||||
|
||||
BOOLEAN := 'true' | 'false'
|
||||
|
||||
SYMBOL := ???
|
||||
|
||||
NUMBER := ???
|
||||
|
||||
HASH := '#!' ???
|
||||
|
||||
|
||||
## Grammar ## ([example](http://docs.python.org/2/reference/grammar.html))
|
||||
|
||||
Hy := HASH | COMMENT | WHITESPACE | Expression
|
||||
|
||||
Expression := OPEN-PAREN Operator Args Close-Paren
|
||||
|
||||
Operator := ???
|
||||
|
||||
Args := Value(*)
|
||||
|
||||
List := OPEN-SQUARE Value(*) CLOSE-SQUARE
|
||||
|
||||
Map := OPEN-CURLY ( Value Value )(*) CLOSE-CURLY
|
||||
|
||||
Value := STRING | CONSTANT | BOOLEAN | SYMBOL | NUMBER | Expression | List | Map
|
||||
|
@ -1,493 +0,0 @@
|
||||
# output ast for cpython 2.7
|
||||
import ast
|
||||
import imp
|
||||
|
||||
from hy.lang.expression import HYExpression
|
||||
from hy.lang.number import HYNumber
|
||||
from hy.lang.string import HYString
|
||||
from hy.lang.symbol import HYSymbol
|
||||
from hy.lang.list import HYList
|
||||
from hy.lang.bool import HYBool
|
||||
from hy.lang.map import HYMap
|
||||
|
||||
|
||||
def _ast_print(node, children, obj):
|
||||
""" Handle `print' statements """
|
||||
return ast.Print(dest=None, values=children, nl=True)
|
||||
|
||||
|
||||
def _ast_raise(node, children, obj):
|
||||
return ast.Raise(type=children[0])
|
||||
|
||||
|
||||
def _ast_binop(node, children, obj):
|
||||
""" Handle basic Binary ops """
|
||||
# operator = Add | Sub | Mult | Div | Mod | Pow | LShift
|
||||
# | RShift | BitOr | BitXor | BitAnd | FloorDiv
|
||||
# XXX: Add these folks in
|
||||
|
||||
inv = node.get_invocation()
|
||||
ops = {"+": ast.Add, "/": ast.Div, "*": ast.Mult, "-": ast.Sub}
|
||||
op = ops[inv['function']]
|
||||
left = children.pop(0)
|
||||
calc = None
|
||||
for child in children:
|
||||
calc = ast.BinOp(left=left, op=op(), right=child)
|
||||
left = calc
|
||||
return calc
|
||||
|
||||
|
||||
def _ast_cmp(node, children, obj):
|
||||
inv = node.get_invocation()
|
||||
ops = {
|
||||
"==": ast.Eq, "<=": ast.LtE, ">=": ast.GtE, ">": ast.Gt, "<": ast.Lt,
|
||||
"!=": ast.NotEq, "in": ast.In, "not-in": ast.NotIn, "is": ast.Is,
|
||||
"is-not": ast.IsNot
|
||||
}
|
||||
op = ops[inv['function']]
|
||||
left = children.pop(0)
|
||||
|
||||
cop = [op()] * len(children)
|
||||
return ast.Compare(left=left, ops=cop, comparators=children)
|
||||
|
||||
|
||||
def _ast_import(tree):
|
||||
i = tree.get_invocation()
|
||||
c = i['args']
|
||||
return ast.Import(names=[ast.alias(name=str(x), asname=None) for x in c])
|
||||
|
||||
|
||||
def _ast_import_from(tree):
|
||||
i = tree.get_invocation()
|
||||
c = i['args']
|
||||
mod = c.pop(0)
|
||||
return ast.ImportFrom(
|
||||
module=str(mod),
|
||||
names=[
|
||||
ast.alias(
|
||||
name=str(x),
|
||||
asname=None
|
||||
) for x in c
|
||||
],
|
||||
level=0
|
||||
)
|
||||
|
||||
|
||||
def _ast_if(node, children, obj):
|
||||
cond = children.pop(0)
|
||||
true = children.pop(0)
|
||||
flse = []
|
||||
if children != []:
|
||||
flse = children.pop(0)
|
||||
|
||||
true = true if isinstance(true, list) else [true]
|
||||
flse = flse if isinstance(flse, list) else [flse]
|
||||
|
||||
true = _adjust_body(true, do_ret=obj.in_fn)
|
||||
flse = _adjust_body(flse, do_ret=obj.in_fn)
|
||||
|
||||
ret = ast.If(test=cond, body=true, orelse=flse)
|
||||
return ret
|
||||
|
||||
|
||||
def _ast_do(node, children, obj):
|
||||
return children
|
||||
|
||||
|
||||
def _ast_return(node, children, obj):
|
||||
return ast.Return(value=children[-1])
|
||||
|
||||
|
||||
def _ast_yield(node, chile, obj):
|
||||
val = chile.pop(0)
|
||||
# XXX: Check to make sure chile is now []
|
||||
return ast.Yield(value=val)
|
||||
|
||||
|
||||
special_cases = {
|
||||
"print": _ast_print,
|
||||
|
||||
"+": _ast_binop, "/": _ast_binop,
|
||||
"-": _ast_binop, "*": _ast_binop,
|
||||
|
||||
"==": _ast_cmp, "<=": _ast_cmp,
|
||||
">=": _ast_cmp, "<": _ast_cmp,
|
||||
">": _ast_cmp, "!=": _ast_cmp,
|
||||
"in": _ast_cmp, "not-in": _ast_cmp,
|
||||
"is": _ast_cmp, "is-not": _ast_cmp,
|
||||
|
||||
"if": _ast_if,
|
||||
"do": _ast_do,
|
||||
"raise": _ast_raise,
|
||||
"yield": _ast_yield
|
||||
}
|
||||
|
||||
|
||||
def _meta_ast_subscript(val, sl, ctx):
|
||||
return ast.Subscript(value=val, slice=sl, ctx=ctx)
|
||||
|
||||
|
||||
class AST27Converter(object):
|
||||
""" Convert a lexed Hy tree into a Python AST for cpython 2.7 """
|
||||
|
||||
def __init__(self):
|
||||
self.table = {
|
||||
HYString: self.render_string,
|
||||
HYExpression: self.render_expression,
|
||||
HYNumber: self.render_number,
|
||||
HYSymbol: self.render_symbol,
|
||||
HYBool: self.render_bool,
|
||||
HYList: self.render_list,
|
||||
HYMap: self.render_map,
|
||||
}
|
||||
|
||||
self.startswith = {
|
||||
".": self._ast_dot
|
||||
}
|
||||
|
||||
self.native_cases = {
|
||||
"defn": self._defn,
|
||||
"fn": self._defn,
|
||||
"def": self._def,
|
||||
"import": _ast_import,
|
||||
|
||||
"import_from": _ast_import_from, # Remember, "-" --> "_"
|
||||
"decorate_with": self._ast_decorate,
|
||||
|
||||
"index": self._ast_index,
|
||||
"set_index": self._ast_set_index,
|
||||
"while": self._ast_while,
|
||||
|
||||
"doseq": self._ast_for,
|
||||
"for": self._ast_for,
|
||||
"kwapply": self._ast_kwapply,
|
||||
}
|
||||
self.special_types = {
|
||||
HYMap: self._ast_fn_index,
|
||||
HYList: self._ast_fn_index,
|
||||
}
|
||||
self.in_fn = False
|
||||
|
||||
def _ast_set_index(self, node):
|
||||
i = node.get_invocation()
|
||||
c = i['args']
|
||||
val = c.pop(0)
|
||||
sl = c.pop(0)
|
||||
tar = c.pop(0)
|
||||
|
||||
return ast.Assign(
|
||||
targets=[
|
||||
_meta_ast_subscript(
|
||||
self.render(val),
|
||||
ast.Index(value=self.render(sl)),
|
||||
ast.Store())
|
||||
],
|
||||
value=self.render(tar)
|
||||
)
|
||||
|
||||
def _ast_index(self, node):
|
||||
i = node.get_invocation()
|
||||
c = i['args']
|
||||
val = c.pop(0)
|
||||
tar = c.pop(0)
|
||||
|
||||
return _meta_ast_subscript(
|
||||
self.render(val),
|
||||
ast.Index(value=self.render(tar), ctx=ast.Load()),
|
||||
ast.Load())
|
||||
|
||||
def _ast_fn_index(self, node):
|
||||
i = node.get_invocation()
|
||||
cmd = ["index"]
|
||||
cmd.append(i['function'])
|
||||
cmd.extend(i['args'])
|
||||
return self.render_expression(HYExpression(cmd))
|
||||
|
||||
def _ast_dot(self, node):
|
||||
inv = node.get_invocation()
|
||||
args = inv['args']
|
||||
target = args.pop(0)
|
||||
attr = inv['function'][1:]
|
||||
|
||||
return ast.Call(
|
||||
func=ast.Attribute(
|
||||
value=self.render(target),
|
||||
attr=str(attr),
|
||||
ctx=ast.Load()
|
||||
),
|
||||
args=[self.render(x) for x in args],
|
||||
keywords=[],
|
||||
starargs=None,
|
||||
kwargs=None
|
||||
)
|
||||
|
||||
def _ast_decorate(self, node):
|
||||
i = node.get_invocation()
|
||||
c = i['args']
|
||||
meth = c.pop(-1)
|
||||
fn = self.render(meth)
|
||||
for chile in c:
|
||||
fn.decorator_list.append(self.render(chile))
|
||||
|
||||
return fn
|
||||
|
||||
def _def(self, node):
|
||||
""" For the `def` operator """
|
||||
inv = node.get_invocation()
|
||||
args = inv['args']
|
||||
name = args.pop(0)
|
||||
blob = self.render(args[0])
|
||||
|
||||
ret = ast.Assign(
|
||||
targets=[ast.Name(id=str(name), ctx=ast.Store())],
|
||||
value=blob
|
||||
)
|
||||
return ret
|
||||
|
||||
def _ast_kwapply(self, node):
|
||||
i = node.get_invocation()
|
||||
args = i['args']
|
||||
fn = args.pop(0)
|
||||
kwargs = args.pop(0)
|
||||
ret = self.render(fn)
|
||||
ret.keywords = [
|
||||
ast.keyword(
|
||||
arg=str(x),
|
||||
value=self.render(kwargs[x])
|
||||
) for x in kwargs
|
||||
]
|
||||
return ret
|
||||
|
||||
def _ast_while(self, node):
|
||||
i = node.get_invocation()
|
||||
args = i['args']
|
||||
test = args.pop(0)
|
||||
test = self.render(test)
|
||||
body = args.pop(0)
|
||||
body = self.render(body)
|
||||
body = body if isinstance(body, list) else [body]
|
||||
orel = []
|
||||
|
||||
body = _adjust_body(body, do_ret=self.in_fn)
|
||||
orel = _adjust_body(orel, do_ret=self.in_fn)
|
||||
|
||||
return ast.While(
|
||||
test=test,
|
||||
body=body,
|
||||
orelse=orel,
|
||||
)
|
||||
|
||||
def _ast_for(self, node):
|
||||
i = node.get_invocation()
|
||||
args = i['args']
|
||||
sig = args.pop(0)
|
||||
body = args.pop(0)
|
||||
aname, seq = sig
|
||||
|
||||
body = self.render(body)
|
||||
body = body if isinstance(body, list) else [body]
|
||||
orel = []
|
||||
|
||||
body = _adjust_body(body, do_ret=False)
|
||||
orel = _adjust_body(orel, do_ret=False)
|
||||
|
||||
return ast.For(
|
||||
target=ast.Name(id=str(aname), ctx=ast.Store()),
|
||||
iter=self.render(seq),
|
||||
body=body,
|
||||
orelse=orel,
|
||||
)
|
||||
|
||||
def _defn(self, node):
|
||||
""" For the defn operator """
|
||||
inv = node.get_invocation()
|
||||
args = inv['args']
|
||||
name = args.pop(0)
|
||||
sig = args.pop(0)
|
||||
doc = None
|
||||
|
||||
if type(args[0]) == HYString:
|
||||
doc = args.pop(0)
|
||||
|
||||
# verify child count...
|
||||
c = []
|
||||
_pop_fn = self.in_fn
|
||||
|
||||
self.in_fn = True
|
||||
for child in args:
|
||||
c.append(self.render(child))
|
||||
|
||||
self.in_fn = _pop_fn
|
||||
|
||||
cont = c[-1] # XXX: Wrong...
|
||||
body = cont if isinstance(cont, list) else [cont]
|
||||
|
||||
if doc:
|
||||
# Shim in docstrings
|
||||
body.insert(0, ast.Expr(value=ast.Str(s=str(doc))))
|
||||
|
||||
body = _adjust_body(body, do_ret=True)
|
||||
|
||||
ret = ast.FunctionDef(
|
||||
name=str(name),
|
||||
args=ast.arguments(
|
||||
args=[
|
||||
ast.Name(
|
||||
arg=str(x),
|
||||
id=str(x),
|
||||
ctx=ast.Param()
|
||||
) for x in sig
|
||||
],
|
||||
vararg=None,
|
||||
kwarg=None,
|
||||
kwonlyargs=[],
|
||||
kw_defaults=[],
|
||||
defaults=[]
|
||||
),
|
||||
body=body,
|
||||
decorator_list=[]
|
||||
)
|
||||
return ret
|
||||
|
||||
def render_string(self, node):
|
||||
""" Render a string to AST """
|
||||
return ast.Str(s=str(node))
|
||||
|
||||
def render_list(self, node):
|
||||
ret = []
|
||||
for c in node:
|
||||
ret.append(self.render(c))
|
||||
return ast.List(elts=ret, ctx=ast.Load())
|
||||
|
||||
def render_map(self, node):
|
||||
keys = []
|
||||
values = []
|
||||
for key in node:
|
||||
keys.append(self.render(key))
|
||||
values.append(self.render(node[key]))
|
||||
return ast.Dict(keys=keys, values=values)
|
||||
|
||||
def render_bool(self, node):
|
||||
""" Render a boolean to AST """
|
||||
thing = "True" if node._val else "False"
|
||||
return ast.Name(id=thing, ctx=ast.Load())
|
||||
|
||||
def render_symbol(self, node):
|
||||
""" Render a symbol to AST """
|
||||
# the only time we have a bare symbol is if we
|
||||
# deref it.
|
||||
if "." in node:
|
||||
glob, local = node.rsplit(".", 1)
|
||||
ret = ast.Attribute(
|
||||
value=self.render_symbol(glob),
|
||||
attr=str(local),
|
||||
ctx=ast.Load()
|
||||
)
|
||||
return ret
|
||||
|
||||
return ast.Name(id=str(node), ctx=ast.Load())
|
||||
|
||||
def render_number(self, node):
|
||||
""" Render a number to AST """
|
||||
return ast.Num(n=node)
|
||||
|
||||
def render_expression(self, node):
|
||||
""" Render an expression (function) to AST """
|
||||
|
||||
inv = node.get_invocation()
|
||||
|
||||
if type(inv['function']) in self.special_types:
|
||||
return self.special_types[type(inv['function'])](node)
|
||||
|
||||
if inv['function'] in self.native_cases:
|
||||
return self.native_cases[inv['function']](node)
|
||||
|
||||
for key in self.startswith:
|
||||
if inv['function'].startswith(key):
|
||||
return self.startswith[key](node)
|
||||
|
||||
c = []
|
||||
for child in node.get_children():
|
||||
c.append(self.render(child))
|
||||
|
||||
if inv['function'] in special_cases:
|
||||
return special_cases[inv['function']](node, c, self)
|
||||
|
||||
ret = ast.Call(
|
||||
func=self.render_symbol(inv['function']),
|
||||
args=c,
|
||||
keywords=[],
|
||||
starargs=None,
|
||||
kwargs=None
|
||||
)
|
||||
return ret
|
||||
|
||||
def render(self, tree):
|
||||
""" Entry point """
|
||||
t = type(tree)
|
||||
handler = self.table[t]
|
||||
ret = handler(tree)
|
||||
|
||||
def _correct_tree(_ast, tree):
|
||||
for node in ast.walk(_ast):
|
||||
node.lineno = tree.line
|
||||
node.col_offset = tree.column
|
||||
|
||||
if isinstance(ret, list):
|
||||
for r in ret:
|
||||
_correct_tree(r, tree)
|
||||
else:
|
||||
_correct_tree(ret, tree)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def _adjust_body(at, do_ret=True):
|
||||
ret = []
|
||||
|
||||
first = True
|
||||
at.reverse()
|
||||
|
||||
for el in at:
|
||||
if not isinstance(el, ast.stmt):
|
||||
if first and do_ret:
|
||||
ret.append(ast.Return(
|
||||
value=el,
|
||||
lineno=el.lineno,
|
||||
col_offset=el.col_offset
|
||||
))
|
||||
else:
|
||||
ret.append(ast.Expr(
|
||||
value=el,
|
||||
lineno=el.lineno,
|
||||
col_offset=el.col_offset
|
||||
))
|
||||
else:
|
||||
ret.append(el)
|
||||
first = False
|
||||
|
||||
ret.reverse()
|
||||
return ret
|
||||
|
||||
|
||||
def forge_ast(name, forest):
|
||||
""" Make an AST for hacking with """
|
||||
conv = AST27Converter()
|
||||
|
||||
statements = []
|
||||
for tree in forest:
|
||||
ret = conv.render(tree)
|
||||
statements.append(ret)
|
||||
|
||||
statements = _adjust_body(statements, do_ret=False)
|
||||
|
||||
return ast.Module(body=statements)
|
||||
#return ast.fix_missing_locations(ast.Module(body=statements))
|
||||
|
||||
|
||||
def forge_module(name, fpath, forest):
|
||||
mod = imp.new_module(name)
|
||||
mod.__file__ = fpath
|
||||
ast = forge_ast(name, forest)
|
||||
eval(compile(ast, fpath, "exec"), mod.__dict__)
|
||||
return mod
|
@ -1,9 +0,0 @@
|
||||
from hy.lang.hyobj import HYObject
|
||||
|
||||
|
||||
class HYBool(HYObject):
|
||||
def __init__(self, val):
|
||||
self._val = val
|
||||
|
||||
def eval(self, lns, *args, **kwargs):
|
||||
return self._val is True
|
@ -1,94 +0,0 @@
|
||||
#
|
||||
import sys
|
||||
from hy.lang.string import HYString
|
||||
|
||||
|
||||
def _define(obj, lns):
|
||||
fd = obj.get_invocation()
|
||||
args = fd['args']
|
||||
obj.namespace[args[0]] = args[1]()
|
||||
|
||||
|
||||
def _loop(obj, lns):
|
||||
fd = obj.get_invocation()
|
||||
args = fd['args']
|
||||
while True:
|
||||
for arg in args:
|
||||
arg.eval(lns.clone())
|
||||
|
||||
|
||||
def _fn(obj, lns, name=None):
|
||||
fd = obj.get_invocation()
|
||||
args = fd['args']
|
||||
sig = args[0]
|
||||
|
||||
docstring = None
|
||||
if isinstance(args[1], HYString):
|
||||
docstring = args.pop(1)
|
||||
|
||||
meth = args[1]
|
||||
|
||||
def _(*args, **kwargs):
|
||||
l = lns.clone()
|
||||
for i in range(0, len(sig)):
|
||||
name = sig[i]
|
||||
value = args[i]
|
||||
l[name] = value
|
||||
|
||||
ret = meth.eval(l, *args, **kwargs)
|
||||
return ret
|
||||
|
||||
_.__name__ = "hyfn"
|
||||
if name:
|
||||
_.__name__ = name
|
||||
|
||||
_.__doc__ = docstring
|
||||
return _
|
||||
|
||||
|
||||
def _kwapply(obj, lns):
|
||||
fd = obj.get_invocation()
|
||||
subshell, kwargs = fd['args']
|
||||
return subshell.eval(lns.clone(), **kwargs)
|
||||
|
||||
|
||||
def _import(obj, lns):
|
||||
ns = obj.namespace
|
||||
fd = obj.get_invocation()
|
||||
args = fd['args']
|
||||
mods = args[0]
|
||||
|
||||
for module in mods:
|
||||
basename = module.split(".", 1)[0]
|
||||
mod = __import__(module)
|
||||
sys.modules[module] = mod
|
||||
ns[basename] = mod
|
||||
|
||||
|
||||
def _progn(obj, lns):
|
||||
fd = obj.get_invocation()
|
||||
args = fd['args']
|
||||
ret = []
|
||||
for arg in args:
|
||||
ret.append(arg.eval(lns.clone()))
|
||||
return ret
|
||||
|
||||
|
||||
def _if(obj, lns):
|
||||
fd = obj.get_invocation()
|
||||
args = fd['args']
|
||||
if args[0].eval(lns.clone()):
|
||||
return args[1].eval(lns.clone())
|
||||
else:
|
||||
return args[2].eval(lns.clone())
|
||||
|
||||
|
||||
builtins = {
|
||||
"def": _define,
|
||||
"fn": _fn,
|
||||
"import": _import,
|
||||
"kwapply": _kwapply,
|
||||
"if": _if,
|
||||
"loop": _loop,
|
||||
"progn": _progn,
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
from hy.lang.hyobj import HYObject
|
||||
from hy.lang.builtins import builtins
|
||||
|
||||
|
||||
class HYExpression(HYObject, list):
|
||||
def __init__(self, nodes):
|
||||
self += nodes
|
||||
|
||||
def get_children(self):
|
||||
ret = []
|
||||
for node in self.get_invocation()['args']:
|
||||
ret.append(node)
|
||||
return ret
|
||||
|
||||
def get_invocation(self):
|
||||
fn = self[0] if len(self) > 0 else ""
|
||||
args = self[1:] if len(self) > 1 else []
|
||||
|
||||
return {
|
||||
"function": fn,
|
||||
"args": args,
|
||||
}
|
||||
|
||||
def peek(self):
|
||||
return self.get_invocation()['function']
|
||||
|
||||
def eval(self, lns, *args, **kwargs):
|
||||
fn = self.peek()
|
||||
|
||||
if fn in builtins:
|
||||
# special-case builtin handling.
|
||||
return builtins[fn](self, lns)
|
||||
|
||||
things = []
|
||||
for child in self.get_children():
|
||||
c = child.copy()
|
||||
things.append(c.eval(lns.clone()))
|
||||
|
||||
ret = self.lookup(lns, fn)(*things, **kwargs)
|
||||
return ret
|
@ -1,49 +0,0 @@
|
||||
from hy.lang.internals import HYNamespaceCOW
|
||||
|
||||
|
||||
class HYObject(object):
|
||||
def set_namespace(self, ns):
|
||||
self.namespace = ns
|
||||
for c in self.get_children():
|
||||
c.set_namespace(ns)
|
||||
|
||||
def get_children(self):
|
||||
return []
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
ns = HYNamespaceCOW({}) # Each invocation needs it's own ns
|
||||
return self.eval(ns, *args, **kwargs)
|
||||
|
||||
def lookup(self, lns, fn):
|
||||
if fn in lns:
|
||||
return lns[fn]
|
||||
|
||||
if fn in self.namespace:
|
||||
return self.namespace[fn]
|
||||
|
||||
if fn in self.namespace['__builtins__']:
|
||||
return self.namespace['__builtins__'][fn]
|
||||
# builtin lookup
|
||||
|
||||
if "." in fn:
|
||||
lon, short = fn.rsplit(".", 1)
|
||||
holder = self.lookup(lns, lon)
|
||||
return getattr(holder, short)
|
||||
|
||||
raise Exception("No such symbol: `%s`" % (fn))
|
||||
|
||||
def eval(self, lns, *args, **kwargs):
|
||||
for node in self.get_children():
|
||||
node.eval(lns, *args, **kwargs)
|
||||
return self
|
||||
|
||||
def _issue_job(self, job, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def _join(self):
|
||||
pass
|
||||
|
||||
def copy(self):
|
||||
new = type(self)(self)
|
||||
new.set_namespace(self.namespace)
|
||||
return new
|
@ -1,77 +0,0 @@
|
||||
# from hy.compiler.modfaker import forge_module
|
||||
from hy.compiler.ast27 import forge_module
|
||||
|
||||
from hy.lex.tokenize import tokenize
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
def _hy_import_file(fd, name):
|
||||
m = forge_module(
|
||||
name,
|
||||
fd,
|
||||
tokenize(open(fd, 'r').read())
|
||||
)
|
||||
return m
|
||||
|
||||
|
||||
class HyFinder(object):
|
||||
def is_package(self, fullname):
|
||||
dirpath = "/".join(fullname.split("."))
|
||||
for pth in sys.path:
|
||||
pth = os.path.abspath(pth)
|
||||
composed_path = "%s/%s/__init__.hy" % (pth, dirpath)
|
||||
if os.path.exists(composed_path):
|
||||
return True
|
||||
return False
|
||||
|
||||
def find_on_path(self, fullname):
|
||||
fls = ["%s/__init__.hy", "%s.hy"]
|
||||
dirpath = "/".join(fullname.split("."))
|
||||
|
||||
for pth in sys.path:
|
||||
pth = os.path.abspath(pth)
|
||||
for fp in fls:
|
||||
composed_path = fp % ("%s/%s" % (pth, dirpath))
|
||||
if os.path.exists(composed_path):
|
||||
return composed_path
|
||||
|
||||
|
||||
class MetaLoader(HyFinder):
|
||||
def load_module(self, fullname):
|
||||
if fullname in sys.modules:
|
||||
return sys.modules[fullname]
|
||||
|
||||
pth = self.find_on_path(fullname)
|
||||
if pth is None:
|
||||
return
|
||||
|
||||
sys.modules[fullname] = None
|
||||
mod = _hy_import_file(pth, fullname)
|
||||
|
||||
ispkg = self.is_package(fullname)
|
||||
|
||||
mod.__file__ = pth
|
||||
mod.__loader__ = self
|
||||
mod.__name__ = fullname
|
||||
|
||||
if ispkg:
|
||||
mod.__path__ = []
|
||||
mod.__package__ = fullname
|
||||
else:
|
||||
mod.__package__ = fullname.rpartition('.')[0]
|
||||
|
||||
sys.modules[fullname] = mod
|
||||
return mod
|
||||
|
||||
|
||||
class MetaImporter(HyFinder):
|
||||
def find_module(self, fullname, path=None):
|
||||
pth = self.find_on_path(fullname)
|
||||
if pth is None:
|
||||
return
|
||||
return MetaLoader()
|
||||
|
||||
|
||||
sys.meta_path.append(MetaImporter())
|
||||
sys.path.insert(0, "")
|
@ -1,23 +0,0 @@
|
||||
#
|
||||
|
||||
|
||||
class HYNamespaceCOW(object):
|
||||
def __init__(self, inmutable_copy):
|
||||
self._inmute = inmutable_copy
|
||||
self._mute = {}
|
||||
|
||||
def __contains__(self, key):
|
||||
if key in self._mute:
|
||||
return True
|
||||
return key in self._inmute
|
||||
|
||||
def __getitem__(self, key):
|
||||
if key in self._mute:
|
||||
return self._mute[key]
|
||||
return self._inmute[key]
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self._mute[key] = value
|
||||
|
||||
def clone(self):
|
||||
return HYNamespaceCOW(self)
|
@ -1,15 +0,0 @@
|
||||
from hy.lang.hyobj import HYObject
|
||||
|
||||
|
||||
class HYList(HYObject, list):
|
||||
def __init__(self, nodes):
|
||||
[self.append(node) for node in nodes]
|
||||
|
||||
def get_children(self):
|
||||
return self
|
||||
|
||||
def eval(self, ln, *args, **kwargs):
|
||||
ret = []
|
||||
for node in self.get_children():
|
||||
ret.append(node.eval(ln, *args, **kwargs))
|
||||
return ret
|
@ -1,15 +0,0 @@
|
||||
from hy.lang.hyobj import HYObject
|
||||
|
||||
|
||||
class HYMap(HYObject, dict):
|
||||
def __init__(self, nodes):
|
||||
for node in nodes:
|
||||
self[node] = nodes[node]
|
||||
|
||||
def get_children(self):
|
||||
ret = []
|
||||
for v in self.keys():
|
||||
ret.append(v)
|
||||
for v in self.values():
|
||||
ret.append(v)
|
||||
return ret
|
@ -1,137 +0,0 @@
|
||||
from hy.lex.tokenize import tokenize as _hy_tok
|
||||
import sys
|
||||
|
||||
|
||||
def _print(*args, **kwargs):
|
||||
sys.stdout.write(" ".join([str(x) for x in args]) + "\n")
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def _read(*args):
|
||||
return sys.stdin.readline()
|
||||
|
||||
|
||||
def _lex(*args):
|
||||
ret = []
|
||||
for thing in args:
|
||||
ret.append(_hy_tok(thing))
|
||||
return ret
|
||||
|
||||
|
||||
def _foreach(*args):
|
||||
a = args[0]
|
||||
for arg in a:
|
||||
args[1](arg)
|
||||
|
||||
|
||||
def _get(*args):
|
||||
m = args[0]
|
||||
k = args[1]
|
||||
if k in m:
|
||||
return m[k]
|
||||
else:
|
||||
if len(args) > 2:
|
||||
return args[2]
|
||||
raise KeyError("No such key `%s` in map." % (k))
|
||||
|
||||
|
||||
def _plus(*args):
|
||||
ret = args[0]
|
||||
args = args[1:]
|
||||
for x in args:
|
||||
ret += x
|
||||
return ret
|
||||
|
||||
|
||||
def _subtract(*args):
|
||||
ret = args[0]
|
||||
args = args[1:]
|
||||
for x in args:
|
||||
ret -= x
|
||||
return ret
|
||||
|
||||
|
||||
def _mult(*args):
|
||||
ret = args[0]
|
||||
args = args[1:]
|
||||
for x in args:
|
||||
ret *= x
|
||||
return ret
|
||||
|
||||
|
||||
def _divide(*args):
|
||||
ret = args[0]
|
||||
args = args[1:]
|
||||
for x in args:
|
||||
ret /= x
|
||||
return ret
|
||||
|
||||
|
||||
def _eq(*args):
|
||||
car, cdr = args[0], args[1:]
|
||||
for arg in cdr:
|
||||
if arg != car:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _ne(*args):
|
||||
seen = set()
|
||||
for arg in args:
|
||||
if arg in seen:
|
||||
return False
|
||||
seen.add(arg)
|
||||
return True
|
||||
|
||||
|
||||
def _gt(*args):
|
||||
for i in range(1, len(args)):
|
||||
if not (args[i - 1] > args[i]):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _ge(*args):
|
||||
for i in range(1, len(args)):
|
||||
if not (args[i - 1] >= args[i]):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _le(*args):
|
||||
for i in range(1, len(args)):
|
||||
if not (args[i - 1] <= args[i]):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _lt(*args):
|
||||
for i in range(1, len(args)):
|
||||
if not (args[i - 1] < args[i]):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _throw(*args):
|
||||
raise args[0]
|
||||
|
||||
|
||||
natives = {
|
||||
"print": _print,
|
||||
"puts": _print,
|
||||
"+": _plus,
|
||||
"-": _subtract,
|
||||
"*": _mult,
|
||||
"/": _divide,
|
||||
"==": _eq,
|
||||
">": _gt,
|
||||
">=": _ge,
|
||||
"<": _lt,
|
||||
"<=": _le,
|
||||
"!=": _ne,
|
||||
"lex": _lex,
|
||||
"read": _read,
|
||||
"foreach": _foreach,
|
||||
"get": _get,
|
||||
"throw": _throw
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
from hy.lang.hyobj import HYObject
|
||||
|
||||
|
||||
class HYNumber(HYObject, int):
|
||||
def __new__(cls, number, *args, **kwargs):
|
||||
number = int(number)
|
||||
return super(HYNumber, cls).__new__(cls, number)
|
||||
|
||||
def eval(self, lns, *args, **kwargs):
|
||||
return int(self)
|
@ -1,17 +0,0 @@
|
||||
from hy.lang.hyobj import HYObject
|
||||
import sys
|
||||
|
||||
|
||||
if sys.version_info[0] >= 3:
|
||||
_str_type = str
|
||||
else:
|
||||
_str_type = unicode
|
||||
|
||||
|
||||
class HYString(HYObject, _str_type):
|
||||
def __new__(cls, value):
|
||||
obj = _str_type.__new__(cls, value)
|
||||
return obj
|
||||
|
||||
def eval(self, ln, *args, **kwargs):
|
||||
return str(self)
|
@ -1,10 +0,0 @@
|
||||
from hy.lang.string import HYString
|
||||
|
||||
|
||||
class HYSymbol(HYString):
|
||||
def __init__(self, string):
|
||||
self += string
|
||||
|
||||
def eval(self, lns, *args, **kwargs):
|
||||
obj = self.lookup(lns, self)
|
||||
return obj
|
@ -1,2 +0,0 @@
|
||||
class LexException(Exception):
|
||||
pass
|
@ -1,29 +0,0 @@
|
||||
class Machine(object):
|
||||
def __init__(self, state):
|
||||
# print "New machine: %s" % (state)
|
||||
self.nodes = []
|
||||
self.state = state(self)
|
||||
self.state.enter()
|
||||
self.line = 1
|
||||
self.column = 1
|
||||
|
||||
def add_node(self, node):
|
||||
node.line = self.line
|
||||
node.column = self.column
|
||||
self.nodes.append(node)
|
||||
|
||||
def process(self, buf):
|
||||
for i in range(0, len(buf)):
|
||||
char = buf[i]
|
||||
|
||||
self.column += 1
|
||||
if char == "\n":
|
||||
self.line += 1
|
||||
self.column = 0
|
||||
|
||||
nx = self.state.process(char)
|
||||
if nx:
|
||||
# print "New state: %s" % (nx)
|
||||
self.state.exit()
|
||||
self.state = nx(self)
|
||||
self.state.enter()
|
250
hy/lex/states.py
250
hy/lex/states.py
@ -1,250 +0,0 @@
|
||||
from hy.lang.expression import HYExpression
|
||||
from hy.lex.errors import LexException
|
||||
from hy.lang.string import HYString
|
||||
from hy.lang.symbol import HYSymbol
|
||||
from hy.lang.number import HYNumber
|
||||
from hy.lex.machine import Machine
|
||||
from hy.lang.list import HYList
|
||||
from hy.lang.bool import HYBool
|
||||
from hy.lang.map import HYMap
|
||||
|
||||
|
||||
WHITESPACE = [" ", "\t", "\n", "\r"]
|
||||
|
||||
|
||||
def _resolve_atom(value, self):
|
||||
def _mangle(obj):
|
||||
obj.line = self.machine.line
|
||||
obj.column = self.machine.column
|
||||
return obj
|
||||
|
||||
if value == "true":
|
||||
return _mangle(HYBool(True))
|
||||
elif value == "false":
|
||||
return _mangle(HYBool(False))
|
||||
|
||||
try:
|
||||
return _mangle(HYNumber(value))
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# LISP Variants tend to use *foo* for constants. Let's make it
|
||||
# the more pythonic "FOO"
|
||||
if value.startswith("*") and value.endswith("*") and len(value) > 1:
|
||||
value = value.upper()[1:-1]
|
||||
|
||||
# LISP Variants have a tendency to use "-" in symbols n' shit.
|
||||
if value != "-": # we need subtraction
|
||||
value = value.replace("-", "_")
|
||||
|
||||
return _mangle(HYSymbol(value))
|
||||
|
||||
|
||||
class State(object):
|
||||
def __init__(self, machine):
|
||||
self.machine = machine
|
||||
self.sub_machine = None
|
||||
|
||||
def enter(self):
|
||||
pass
|
||||
|
||||
def exit(self):
|
||||
pass
|
||||
|
||||
def sub(self, machine):
|
||||
self.sub_machine = Machine(machine)
|
||||
|
||||
def process(self, x):
|
||||
if self.sub_machine:
|
||||
self.sub_machine.process(x)
|
||||
idle = type(self.sub_machine.state) == Idle
|
||||
if idle:
|
||||
self.nodes += self.sub_machine.nodes
|
||||
self.sub_machine = None
|
||||
return
|
||||
|
||||
return self.p(x)
|
||||
|
||||
|
||||
class Comment(State):
|
||||
def p(self, x):
|
||||
if x == '\n':
|
||||
return Idle
|
||||
|
||||
|
||||
class Idle(State):
|
||||
def p(self, x):
|
||||
if x == "#":
|
||||
return HashExpression
|
||||
if x == ";":
|
||||
return Comment
|
||||
if x == "(":
|
||||
return Expression
|
||||
if x in WHITESPACE:
|
||||
return
|
||||
|
||||
raise LexException("Unknown char: %s" % (x))
|
||||
|
||||
|
||||
class HashExpression(State):
|
||||
def p(self, x):
|
||||
if x == "!":
|
||||
return Comment
|
||||
|
||||
raise LexException("Unknwon Hash modifier - %s" % (x))
|
||||
|
||||
|
||||
class Expression(State):
|
||||
def enter(self):
|
||||
self.nodes = HYExpression([])
|
||||
self.bulk = ""
|
||||
|
||||
def exit(self):
|
||||
if self.bulk:
|
||||
self.nodes.append(_resolve_atom(self.bulk, self))
|
||||
|
||||
self.machine.add_node(self.nodes)
|
||||
|
||||
def commit(self):
|
||||
if self.bulk.strip() != "":
|
||||
self.nodes.append(_resolve_atom(self.bulk, self))
|
||||
self.bulk = ""
|
||||
|
||||
def p(self, x):
|
||||
if x == ")":
|
||||
return Idle
|
||||
if x in WHITESPACE:
|
||||
self.commit()
|
||||
return
|
||||
if x == "\"":
|
||||
self.sub(String)
|
||||
return
|
||||
if x == "(":
|
||||
self.sub(Expression)
|
||||
return
|
||||
if x == "[":
|
||||
self.sub(List)
|
||||
return
|
||||
if x == "{":
|
||||
self.sub(Map)
|
||||
return
|
||||
if x == ";":
|
||||
self.sub(Comment)
|
||||
return
|
||||
self.bulk += x
|
||||
|
||||
|
||||
class List(State):
|
||||
def enter(self):
|
||||
self.nodes = HYList([])
|
||||
self.bulk = ""
|
||||
|
||||
def exit(self):
|
||||
if self.bulk:
|
||||
self.nodes.append(_resolve_atom(self.bulk, self))
|
||||
self.machine.add_node(self.nodes)
|
||||
|
||||
def commit(self):
|
||||
if self.bulk.strip() != "":
|
||||
self.nodes.append(_resolve_atom(self.bulk, self))
|
||||
self.bulk = ""
|
||||
|
||||
def p(self, x):
|
||||
if x == "]":
|
||||
return Idle
|
||||
if x in WHITESPACE:
|
||||
self.commit()
|
||||
return
|
||||
if x == "\"":
|
||||
self.sub(String)
|
||||
return
|
||||
if x == "[":
|
||||
self.sub(List)
|
||||
return
|
||||
if x == "(":
|
||||
self.sub(Expression)
|
||||
return
|
||||
if x == "{":
|
||||
self.sub(Map)
|
||||
return
|
||||
if x == ";":
|
||||
self.sub(Comment)
|
||||
return
|
||||
self.bulk += x
|
||||
|
||||
|
||||
class Map(State):
|
||||
def enter(self):
|
||||
self.nodes = []
|
||||
self.bulk = ""
|
||||
|
||||
def exit(self):
|
||||
if self.bulk:
|
||||
self.nodes.append(_resolve_atom(self.bulk, self))
|
||||
|
||||
if (len(self.nodes) % 2) != 0:
|
||||
raise LexException("Hash map is screwed up")
|
||||
|
||||
ret = HYMap({})
|
||||
i = iter(self.nodes)
|
||||
hmap = zip(i, i)
|
||||
for key, val in hmap:
|
||||
ret[key] = val
|
||||
self.machine.add_node(ret)
|
||||
|
||||
def commit(self):
|
||||
if self.bulk.strip() != "":
|
||||
self.nodes.append(_resolve_atom(self.bulk, self))
|
||||
self.bulk = ""
|
||||
|
||||
def p(self, x):
|
||||
if x == "}":
|
||||
return Idle
|
||||
if x in WHITESPACE:
|
||||
self.commit()
|
||||
return
|
||||
if x == "\"":
|
||||
self.sub(String)
|
||||
return
|
||||
if x == "[":
|
||||
self.sub(List)
|
||||
return
|
||||
if x == "{":
|
||||
self.sub(Map)
|
||||
return
|
||||
if x == "(":
|
||||
self.sub(Expression)
|
||||
return
|
||||
if x == ";":
|
||||
self.sub(Comment)
|
||||
return
|
||||
self.bulk += x
|
||||
|
||||
|
||||
class String(State):
|
||||
magic = {"n": "\n", "t": "\t", "\\": "\\", "\"": "\""}
|
||||
|
||||
def enter(self):
|
||||
self.buf = ""
|
||||
self.esc = False
|
||||
|
||||
def exit(self):
|
||||
self.machine.add_node(HYString(self.buf))
|
||||
|
||||
def p(self, x):
|
||||
if x == "\\":
|
||||
self.esc = True
|
||||
return
|
||||
|
||||
if x == "\"" and not self.esc:
|
||||
return Idle
|
||||
|
||||
if self.esc and x not in self.magic:
|
||||
raise LexException("Unknown escape: \\%s" % (x))
|
||||
|
||||
elif self.esc:
|
||||
x = self.magic[x]
|
||||
|
||||
self.esc = False
|
||||
|
||||
self.buf += x
|
@ -1,11 +0,0 @@
|
||||
from hy.lex.machine import Machine
|
||||
from hy.lex.states import Idle
|
||||
from hy.lex.errors import LexException
|
||||
|
||||
|
||||
def tokenize(buff):
|
||||
m = Machine(Idle)
|
||||
m.process(buff)
|
||||
if type(m.state) != Idle:
|
||||
raise LexException("Reached end of file before we were done parsing")
|
||||
return m.nodes
|
@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Pulling repo."
|
||||
ssh metatron.pault.ag "cd /srv/www/uwsgi/app/hy; git pull"
|
||||
ssh -l www metatron.pault.ag "kill-apps; start-apps"
|
@ -1,3 +0,0 @@
|
||||
flake8
|
||||
nose
|
||||
coverage
|
@ -1,5 +0,0 @@
|
||||
[nosetests]
|
||||
detailed-errors=1
|
||||
with-coverage=1
|
||||
cover-package=hy
|
||||
nocapture=1
|
32
setup.py
32
setup.py
@ -1,32 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
long_description = """This thing does stuff and
|
||||
things with other things until things looks like other
|
||||
things. """
|
||||
|
||||
appname = "hy"
|
||||
version = "0.8.2"
|
||||
|
||||
setup(**{
|
||||
"name": appname,
|
||||
"version": version,
|
||||
"packages": [
|
||||
'hy',
|
||||
'hy.lang',
|
||||
'hy.lex',
|
||||
'hy.compiler'
|
||||
],
|
||||
"author": "Paul Tagliamonte",
|
||||
"author_email": "tag@pault.ag",
|
||||
"long_description": long_description,
|
||||
"description": 'lisp and python love eachother',
|
||||
"license": "Expat",
|
||||
"url": "http://hy.pault.ag/",
|
||||
"platforms": ['any'],
|
||||
"scripts": [
|
||||
"bin/hython",
|
||||
"bin/bhython"
|
||||
]
|
||||
})
|
@ -1,5 +0,0 @@
|
||||
(defn test-map-index []
|
||||
({"foo" "bar"} "foo"))
|
||||
|
||||
(defn test-list-index []
|
||||
(["first" "second"] 1))
|
@ -1,4 +0,0 @@
|
||||
; vim: tabstop=2 expandtab shiftwidth=2 softtabstop=2 filetype=lisp
|
||||
|
||||
(defn square [arg]
|
||||
(* arg arg))
|
@ -1,9 +0,0 @@
|
||||
; vim: tabstop=2 expandtab shiftwidth=2 softtabstop=2 filetype=lisp
|
||||
|
||||
(import "tests.lang.test_kwargs")
|
||||
|
||||
(defn kiwi []
|
||||
(kwapply (tests.lang.test_kwargs.shim "one" "two") {
|
||||
"three" "three"
|
||||
"four" "four"
|
||||
}))
|
@ -1,34 +0,0 @@
|
||||
from hy.lex.tokenize import tokenize
|
||||
from hy.lang.expression import HYExpression
|
||||
|
||||
code = """
|
||||
(+ 1 1) ; this is a test.
|
||||
(fn foo bar) ; this is a test.
|
||||
"""
|
||||
|
||||
|
||||
def test_basics():
|
||||
"""Test the basics"""
|
||||
assert {
|
||||
"function": "fn",
|
||||
"args": [
|
||||
"one"
|
||||
]
|
||||
} == HYExpression(["fn", "one"]).get_invocation()
|
||||
|
||||
|
||||
def test_fn_split():
|
||||
"""Test if we can get a statement something right."""
|
||||
one, two = tokenize(code)
|
||||
assert one.get_invocation() == {
|
||||
"function": "+",
|
||||
"args": [
|
||||
1, 1
|
||||
]
|
||||
}
|
||||
assert two.get_invocation() == {
|
||||
"function": "fn",
|
||||
"args": [
|
||||
"foo", "bar"
|
||||
]
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
import hy.lang.importer
|
||||
import tests.lang.foo
|
||||
|
||||
|
||||
def square(x):
|
||||
return x * x
|
||||
|
||||
|
||||
def test_squares_properly():
|
||||
assert tests.lang.foo.square
|
||||
assert tests.lang.foo.square(2) == 4
|
||||
for x in range(0, 10):
|
||||
tests.lang.foo.square(x)
|
@ -1,18 +0,0 @@
|
||||
import hy.lang.importer
|
||||
|
||||
|
||||
def shim(*args, **kwargs):
|
||||
return {"a": args,
|
||||
"k": kwargs}
|
||||
|
||||
|
||||
def test_kwargs_proper():
|
||||
import tests.lang.kwargs
|
||||
val = tests.lang.kwargs.kiwi()
|
||||
assert val == {
|
||||
"a": ('one', 'two'),
|
||||
"k": {
|
||||
"three": "three",
|
||||
"four": "four"
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
from hy.lex.tokenize import tokenize
|
||||
|
||||
def test_map_lex():
|
||||
assert tokenize('(def {"foo" "bar"})') == [['def', {'foo': 'bar'}]]
|
||||
|
||||
|
||||
def test_map_lex():
|
||||
assert tokenize('(def {"foo" "bar" "baz" {"one" "two"}})') == [
|
||||
['def', {
|
||||
'foo': 'bar',
|
||||
'baz': {
|
||||
"one": "two"
|
||||
}
|
||||
}]
|
||||
]
|
@ -1,7 +0,0 @@
|
||||
import tests.lang.colls
|
||||
|
||||
def test_map_index():
|
||||
assert tests.lang.colls.test_map_index() == "bar"
|
||||
|
||||
def test_list_index():
|
||||
assert tests.lang.colls.test_list_index() == "second"
|
@ -1,80 +0,0 @@
|
||||
from hy.lex.tokenize import tokenize
|
||||
|
||||
|
||||
def test_simple_tokenize():
|
||||
"""Checking we can still handle something simple."""
|
||||
|
||||
assert [["+", 1, 1]] == tokenize("(+ 1 1)")
|
||||
|
||||
|
||||
def test_double_tokenize():
|
||||
"""Checking if we can lex two things at once."""
|
||||
|
||||
assert [
|
||||
["+", 1, 2],
|
||||
["-", 1, 1]
|
||||
] == tokenize("(+ 1 2) (- 1 1)")
|
||||
|
||||
|
||||
def test_simple_recurse():
|
||||
""" Test recursion """
|
||||
assert [
|
||||
['fn',
|
||||
'one',
|
||||
['fn', 'two'],
|
||||
]
|
||||
] == tokenize("(fn one (fn two))")
|
||||
|
||||
|
||||
def test_mid_recurse():
|
||||
""" Test some crazy recursion """
|
||||
|
||||
assert [
|
||||
['fn',
|
||||
'one',
|
||||
['fn', 'two'],
|
||||
['fn', 'three'],
|
||||
]
|
||||
] == tokenize("(fn one (fn two)(fn three))")
|
||||
|
||||
|
||||
def test_mid_recurse_comment():
|
||||
""" Test some crazy recursion with a comment """
|
||||
|
||||
assert [
|
||||
['fn',
|
||||
'one',
|
||||
['fn', 'two'],
|
||||
['fn', 'three'],
|
||||
]
|
||||
] == tokenize("""
|
||||
(fn one ; this is a test
|
||||
(fn two)(fn three)) ; and so is this
|
||||
""")
|
||||
|
||||
|
||||
def test_full_recurse():
|
||||
""" Test something we could see for real """
|
||||
assert [
|
||||
['fn',
|
||||
'el',
|
||||
['+',
|
||||
1,
|
||||
2,
|
||||
['==',
|
||||
1,
|
||||
20
|
||||
],
|
||||
['-',
|
||||
1,
|
||||
1
|
||||
],
|
||||
]
|
||||
],
|
||||
['fn1', 'foo', 'bar']
|
||||
] == tokenize("(fn el (+ 1 2 (== 1 20) (- 1 1)))(fn1 foo bar)")
|
||||
|
||||
|
||||
def test_string():
|
||||
""" Lex a lone string """
|
||||
assert ['"a string"'] == tokenize('"a string"')
|
@ -1,44 +0,0 @@
|
||||
from hy.lex.tokenize import tokenize
|
||||
|
||||
|
||||
def test_list_lex():
|
||||
"""test basic lexing of lists"""
|
||||
fn = tokenize("(fn [1 2 3 4])")[0]
|
||||
assert fn == [
|
||||
"fn", [1, 2, 3, 4]
|
||||
]
|
||||
|
||||
|
||||
def test_list_recurse():
|
||||
""" test we can recurse lists """
|
||||
fn = tokenize("(fn [1 2 3 4 [5 6 7]])")[0]
|
||||
assert fn == [
|
||||
"fn", [1, 2, 3, 4, [5, 6, 7]]
|
||||
]
|
||||
|
||||
|
||||
def test_double_rainbow():
|
||||
""" DOUBLE LISTS """
|
||||
fn = tokenize("(fn [1 2 3 4] [5 6 7])")[0]
|
||||
assert fn == [
|
||||
"fn", [1, 2, 3, 4], [5, 6, 7]
|
||||
]
|
||||
|
||||
|
||||
def test_string_in_list():
|
||||
""" String in list """
|
||||
fn = tokenize('(fn [1 2 "three four" 5])')[0]
|
||||
assert fn == [
|
||||
"fn", [1, 2, "three four", 5]
|
||||
]
|
||||
|
||||
|
||||
def test_list_recurse_with_comment():
|
||||
""" test we can recurse lists """
|
||||
fn = tokenize("""
|
||||
(fn [1 ; this is a test
|
||||
2 3 4 [5 6 7]])
|
||||
""")[0]
|
||||
assert fn == [
|
||||
"fn", [1, 2, 3, 4, [5, 6, 7]]
|
||||
]
|
Loading…
x
Reference in New Issue
Block a user