diff options
| -rw-r--r-- | .gitignore | 4 | ||||
| -rw-r--r-- | README.md | 21 | ||||
| -rw-r--r-- | build.hy | 78 | ||||
| -rw-r--r-- | hello.hy | 47 | ||||
| -rw-r--r-- | icon.svg | 14 |
5 files changed, 164 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..558691a --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +__pycache__ +cert.pem +key.pem +out.apk diff --git a/README.md b/README.md new file mode 100644 index 0000000..b0386bf --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# DUCK Hy Proof-of-Concept + +Proof of concept for creating an Android app with +[Hy](http://docs.hylang.org/en/stable/) and David Boddie's +[DUCK](http://www.boddie.org.uk/david/Projects/Python/DUCK/README.html). + +## Building + +Begin by following the directions listed in the ['Getting +Started'](http://www.boddie.org.uk/david/Projects/Python/DUCK/Documents/Getting_Started.html) +section of DUCK's documentation. Now, install the latest version of Hy: + +```sh +$ pip install git+https://github.com/hylang/hy.git +``` + +The build script should now work. + +```sh +$ hy build.hy <key file> <certificate file> out.apk +``` diff --git a/build.hy b/build.hy new file mode 100644 index 0000000..1737d98 --- /dev/null +++ b/build.hy @@ -0,0 +1,78 @@ +#!/usr/bin/env hy + +;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.lonestar.org> +;;; +;;; This program is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU General Public License as +;;; published by the Free Software Foundation; either version 3 of the +;;; License, or (at your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program. If not, see +;;; <http://www.gnu.org/licenses/>. + +(require [hy.contrib.walk [let]]) + +(import [ast [parse Return]]) +(import [copy [deepcopy]]) +(import [os [getenv]]) +(import [os.path [splitext]]) +(import [sys [argv exit]]) + +(import [hy.compiler [hy-compile]]) +(import [hy.lex [hy-parse]]) + +(import DUCK.Serpentine.visitor) +(import [DUCK.Tools [buildhelper]]) + +(defn walk-ast [node] + (when (and (isinstance node Return) + (= node.value.id "None")) + (setv node.value.id None)) + (when (hasattr node "body") + (for [child node.body] + (walk-ast child)))) + +(defn my-hy-compile [source] + (let [ast (hy-compile (hy-parse source) "<unknown>")] + (walk-ast ast) + ast)) + +(defclass HyVisitor [DUCK.Serpentine.visitor.Visitor] + (defn load [self file-name &optional [imports None]] + (let [imports (or imports {})] + (setv self.imports imports) + (setv self.file-name- file-name) + (try + (with [source (open file-name :encoding (.get-coding self file-name))] + (setv self.root (if (.endswith file-name ".hy") + (my-hy-compile (.read source)) + (parse (.read source))))) + (except [err SyntaxError] + (.write stderr (.format "In '{}': " file-name)) + (raise err))) + (let [module (.visit self self.root)] + (assoc self.imports (first (splitext file-name)) module) + (return module))))) + +(setv DUCK.Serpentine.visitor.Visitor HyVisitor) + +(when (= __name__ "__main__") + (let [app-name "HelloHy" + package-name "com.example.hellohy" + res-files {"drawable" {"ic_launcher" "icon.svg"}} + code-file "hello.hy" + include-paths [] + layout None + features [] + permissions [] + docs-dir (getenv "DOCS_DIR") + args (deepcopy argv)] + (exit (.main buildhelper __file__ app-name package-name + res-files layout code-file include-paths + features permissions args :docs-dir docs-dir)))) diff --git a/hello.hy b/hello.hy new file mode 100644 index 0000000..25e3b2d --- /dev/null +++ b/hello.hy @@ -0,0 +1,47 @@ +;; Hello Example +;; ============= +;; +;; This is a simple "Hello world!" example, written in Hy. +;; +;; We begin by declaring a unique namespace for the package we are creating. +;; This is typically based on the reversed form of a domain name and should be +;; unique to this package. + +(setv __package__ "com.example.hellohy") + +;; We also import the classes that will be needed by the application. Since this +;; is a simple example, we only need three of them. + +(import [android.app [Activity]]) +(import [android.os [Bundle]]) +(import [android.widget [TextView]]) + +;; We define a class based on the standard Activity class. This represents the +;; application, and will be used to present a graphical interface to the user. +;; +;; The initialisation method simply calls the corresponding method in the base +;; class. This must be done even if no other code is included in the method. + +(defclass HelloActivity [Activity] + (defn __init__ [self] + (.__init__ Activity self)) + + ;; The onCreate method is called when the activity is created by Android. The + ;; return type and parameter types expected by the method are declared using + ;; the following decorator. Since the parameter types for the onCreate method + ;; are defined in the Activity base class, this decorator is not strictly + ;; necessary. + (with-decorator (args void [Bundle]) + (defn onCreate [self bundle] + (.onCreate Activity self bundle) + (setv view (TextView self)) + (.setText view "Hello world!") + (.setContentView self view) + (return None)))) + +;; As with the `__init__` method, we must call the corresponding method in the +;; base class. +;; +;; The user interface for the application is simply a TextView widget that +;; displays a string of text. The final call ensures that the widget is used as +;; the main view for the application. diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..1c57738 --- /dev/null +++ b/icon.svg @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> + +<svg version="1.1" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + width="1.5cm" height="1.5cm" + viewBox="0 0 100 100"> + +<circle cx="50" cy="50" r="45" stroke="white" fill="#3399ff" stroke-width="2" /> +<circle cx="50" cy="50" r="25" stroke="white" fill="#33ff99" stroke-width="2" /> + +</svg> |