├── .gitignore ├── README.md ├── Run.hx ├── build_run.hxml ├── docs ├── .nojekyll ├── README.md ├── _sidebar.md ├── example │ └── blink.md ├── haxe │ ├── about.md │ ├── choosing-a-code-editor.md │ ├── code │ │ ├── Test.hx │ │ ├── build.hxml │ │ ├── test.html │ │ └── test.js │ ├── hello-world.md │ ├── index.md │ ├── installation.md │ ├── learn-haxe.md │ └── quick-install.md ├── img │ ├── Arduino_Logo.svg │ ├── Haxe_logo.svg │ ├── arduino_haxe_logo.png │ ├── arduino_haxe_logo.svg │ ├── banner.png │ └── haxe_logo.png ├── index.html ├── notes │ ├── baud.md │ ├── docsify.md │ ├── main.md │ ├── ports.md │ ├── syntax.md │ ├── system.md │ └── todo.md └── start │ ├── getting_started.md │ ├── linux.md │ ├── osx.md │ └── windows.md ├── examples ├── 01-blink │ ├── 01-blink.hxproj │ ├── build.hxml │ └── src │ │ └── Main.hx ├── 02-digital-input │ ├── 02-digital-input.hxproj │ ├── build.hxml │ └── src │ │ └── Main.hx ├── 03-arrays-loops │ ├── 03-arrays-loops.hxproj │ ├── build.hxml │ └── src │ │ └── Main.hx ├── 04-objects-heap │ ├── 04-objects-heap.hxproj │ ├── build.hxml │ └── src │ │ ├── Main.hx │ │ └── test │ │ ├── Test1.hx │ │ └── Test2.hx ├── 05-objects-stack │ ├── 05-objects-stack.hxproj │ ├── build.hxml │ └── src │ │ ├── Main.hx │ │ └── test │ │ ├── Test1.hx │ │ └── Test2.hx └── 06-advanced-type-objects │ ├── 06-advanced-type-objects.hxproj │ ├── build.hxml │ └── src │ ├── Main.hx │ └── foo │ ├── BarClass.hx │ ├── Extender.hx │ ├── FooAbstract.hx │ ├── Literals.hx │ ├── SampleFromSite.hx │ └── Varianse.hx ├── extraParams.hxml ├── haxelib.json ├── lib ├── AutoPtr.h ├── HxObject.h ├── LinkedList.h ├── MemoryFree.cpp ├── MemoryFree.h ├── RefCountedObject.h └── entry.cpp ├── run.n ├── src ├── Arduino.hx ├── EEPROM.hx ├── Keyboard.hx ├── LiquidCrystal.hx ├── MemoryFree.hx ├── Mouse.hx ├── Serial.hx ├── Util.hx ├── ast2obj │ ├── Generator.hx │ ├── OArray.hx │ ├── OArrayDecl.hx │ ├── OBinOp.hx │ ├── OBlock.hx │ ├── OCall.hx │ ├── OCase.hx │ ├── OClass.hx │ ├── OClassVar.hx │ ├── OConstant.hx │ ├── OConstantIdentifier.hx │ ├── OExpression.hx │ ├── OFieldInstance.hx │ ├── OFieldStatic.hx │ ├── OIf.hx │ ├── OLocal.hx │ ├── OMethod.hx │ ├── OMethodArg.hx │ ├── ONew.hx │ ├── OParenthesis.hx │ ├── OReturn.hx │ ├── OSwitch.hx │ ├── OThis.hx │ ├── OType.hx │ ├── OTypeExprClass.hx │ ├── OUnOp.hx │ ├── OVar.hx │ ├── OWhile.hx │ └── builders │ │ ├── ArduinoCPPBuilder.hx │ │ ├── Compiler.hx │ │ ├── Installer.hx │ │ └── Monitor.hx ├── firmware │ └── hardware │ │ ├── AtMega2560.hx │ │ ├── AtMega328P.hx │ │ ├── MCU.hx │ │ ├── MegaAtMega2560.hx │ │ └── NanoAtMega328p.hx └── helpers │ ├── FileHelper.hx │ ├── HaxeLibHelper.hx │ ├── ProcessHelper.hx │ └── SizeHelper.hx └── submit.bat /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | temp/ 11 | container-src/temp/ 12 | *.tmp 13 | *.bak 14 | *.swp 15 | *~.nib 16 | local.properties 17 | .classpath 18 | .settings/ 19 | .loadpath 20 | 21 | # External tool builders 22 | .externalToolBuilders/ 23 | 24 | # Locally stored "Eclipse launch configurations" 25 | *.launch 26 | 27 | # CDT-specific 28 | .cproject 29 | 30 | # PDT-specific 31 | .buildpath 32 | 33 | 34 | ################# 35 | ## Visual Studio 36 | ################# 37 | 38 | ## Ignore Visual Studio temporary files, build results, and 39 | ## files generated by popular Visual Studio add-ons. 40 | 41 | # User-specific files 42 | *.suo 43 | *.user 44 | *.sln.docstates 45 | 46 | # Build results 47 | *_i.c 48 | *_p.c 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.vspscc 63 | .builds 64 | *.dotCover 65 | 66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 67 | #packages/ 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | 76 | # Visual Studio profiler 77 | *.psess 78 | *.vsp 79 | 80 | # ReSharper is a .NET coding add-in 81 | _ReSharper* 82 | 83 | # Installshield output folder 84 | [Ee]xpress 85 | 86 | # DocProject is a documentation generator add-in 87 | DocProject/buildhelp/ 88 | DocProject/Help/*.HxT 89 | DocProject/Help/*.HxC 90 | DocProject/Help/*.hhc 91 | DocProject/Help/*.hhk 92 | DocProject/Help/*.hhp 93 | DocProject/Help/Html2 94 | DocProject/Help/html 95 | 96 | # Click-Once directory 97 | publish 98 | 99 | # Others 100 | [Bb]in 101 | [Oo]bj 102 | sql 103 | TestResults 104 | *.Cache 105 | ClientBin 106 | stylecop.* 107 | ~$* 108 | *.dbmdl 109 | Generated_Code #added for RIA/Silverlight projects 110 | 111 | # Backup & report files from converting an old project file to a newer 112 | # Visual Studio version. Backup files are not needed, because we have git ;-) 113 | _UpgradeReport_Files/ 114 | Backup*/ 115 | UpgradeLog*.XML 116 | 117 | 118 | 119 | ############ 120 | ## Windows 121 | ############ 122 | 123 | # Windows image file caches 124 | Thumbs.db 125 | 126 | # Folder config file 127 | Desktop.ini 128 | 129 | 130 | ############# 131 | ## Python 132 | ############# 133 | 134 | *.py[co] 135 | 136 | # Packages 137 | *.egg 138 | *.egg-info 139 | dist 140 | build 141 | eggs 142 | parts 143 | bin 144 | var 145 | sdist 146 | develop-eggs 147 | .installed.cfg 148 | 149 | # Installer logs 150 | pip-log.txt 151 | 152 | # Unit test / coverage reports 153 | .coverage 154 | .tox 155 | 156 | #Translations 157 | *.mo 158 | 159 | #Mr Developer 160 | .mr.developer.cfg 161 | 162 | # Mac crap 163 | .DS_Store 164 | 165 | 166 | *.backup 167 | dox.xml 168 | 169 | Kha/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # hxArduino 3 | 4 | * Includes basic Arduino externs (`Arduino`, `LiquidCrystal`, `MemoryFree`, see: `/lib`) 5 | * Custom C++ generator 6 | * Compiler utility class to compile & link generated c++ 7 | * Installer utility class to push to Arduino device 8 | * Monintor utility class to start reading from serial com port via hxSerial for program traces 9 | 10 | # Usage 11 | 12 | * `haxelib install hxArduino` 13 | * `haxe -lib hxArduino -cp src -no-output -main Main` 14 | * `haxelib run hxArduino -test` 15 | 16 | # Notes 17 | * Must have an `ARDUINO_HOME` environment variable set (eg: `C:\\PROGRA~2\\Arduino`) 18 | * Currently skips alot of haxe "internal" classes (no point in trying to generated them till generator is at least all wired up) 19 | * main.cpp (not generated) makes assumption that there is a `Main.h` and a `Main` c++ class in entry point, eg: 20 | 21 | See examples for various examples 22 | -------------------------------------------------------------------------------- /Run.hx: -------------------------------------------------------------------------------- 1 | package; 2 | import ast2obj.builders.Installer; 3 | import ast2obj.builders.Monitor; 4 | 5 | class Run { 6 | public static function main() { 7 | haxe.Log.trace = function(v:Dynamic, ?infos:haxe.PosInfos) { 8 | Sys.println(v); 9 | } 10 | 11 | if (Sys.args().length < 2) { 12 | trace("Not enough args"); 13 | return; 14 | } 15 | 16 | var args = Sys.args(); 17 | var command = args.shift(); 18 | var dir = args.pop(); 19 | 20 | var cwd = Sys.getCwd(); 21 | Sys.setCwd(dir); 22 | 23 | switch (command) { 24 | case 'install', '--install': 25 | runCommand("install", args); 26 | Sys.getChar(false); 27 | case 'monitor', '--monitor': 28 | runCommand("monitor", args); 29 | case '-p', 'portlist', '--portlist': 30 | runCommand("portlist", args); 31 | case 'test', '--test': 32 | runCommand("install", args); 33 | runCommand("monitor", args); 34 | case '-v', '--version', 'version': 35 | trace('Something clever, but not functional at this moment'); 36 | case '-h', '--help', 'help': 37 | trace(''); 38 | trace('[hxArduino] : custom haxe generator to create arduino specific c++'); 39 | trace(''); 40 | trace('Usage: haxelib run hxArduino [--install/--monitor/--test/--portlist/--help/--version] [-file FOO] [-port BAR]'); 41 | trace(''); 42 | trace('Optional arguments:'); 43 | trace(' --install Install Arduino code on device.'); 44 | trace(' --monitor Monitor ports.'); 45 | trace(' --test Install and monitor.'); 46 | trace(' -p, --portlist Get list of connected ports.'); 47 | trace(' -h, --help Show this help message and exit.'); 48 | trace(' -v, --version Show program\'s version number and exit.'); 49 | trace(' -file Install hexfile (no idea?).'); 50 | trace(' -port Port to use.'); 51 | trace(' -speed baudrate (default detecting by board code).'); 52 | trace(' -boardcode board code (atmega1284, etc).'); 53 | default : 54 | trace("Unknown command '" + command + "'"); 55 | trace("case '"+command+"': trace ('"+command+"');"); 56 | } 57 | 58 | Sys.setCwd(cwd); 59 | } 60 | 61 | private static function runCommand(command:String, args:Array) { 62 | if (command == "install") { 63 | var hexFile:String = extractArg(args, "-file"); 64 | var port:String = extractArg(args, "-port"); 65 | var speed:String = extractArg(args, "-speed"); 66 | var boardcode:String = extractArg(args, "-boardcode"); 67 | Installer.install(hexFile, port, Std.parseInt(speed), boardcode); 68 | } else if (command == "monitor") { 69 | var port:String = extractArg(args, "-port"); 70 | var speed:String = extractArg(args, "-speed"); 71 | var boardcode:String = extractArg(args, "-boardcode"); 72 | Monitor.monitor(port, Std.parseInt(speed), boardcode); 73 | } else if (command == "portlist") { 74 | Monitor.portlist(); 75 | } 76 | } 77 | 78 | public static function extractArg(args:Array, name:String):String { 79 | var v = null; 80 | for (i in 0...args.length) { 81 | if (args[i] == name) { 82 | v = args[i + 1]; 83 | break; 84 | } 85 | } 86 | return v; 87 | } 88 | } -------------------------------------------------------------------------------- /build_run.hxml: -------------------------------------------------------------------------------- 1 | -cp src 2 | -main Run 3 | -lib hxSerial 4 | -neko run.n 5 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ianharrigan/hxArduino/e831388db25159ae57b7773905f14c7d6886c5c4/docs/.nojekyll -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # hxArduino 2 | 3 | ![](img/arduino_haxe_logo.png) 4 | 5 | What happens when you combine [Haxe](https://haxe.org/) with [Arduino](https://www.arduino.cc/)? 6 | 7 | Haxe has the ability to transpile to cpp, so it's in the realm of posiblities. 8 | 9 | Ian Harrigan, a freelance software engineer and creator of [haxeui](http://haxeui.org/) asked the same question. 10 | 11 | It was an itch that needed to be scratched. And voila! it's possible! 12 | 13 | **this project is in its early stages (WIP), be patient!** 14 | 15 | Or as Ian put it 16 | 17 | > NOTE: im in the process of rewriting the generator to make MUCH nicer output c++, basic GC (auto pointers), etc, etc - so far seems to be working nicely! Stay tuned!! 18 | 19 | 20 | * Includes basic Arduino externs (`Arduino`, `LiquidCrystal`, `MemoryFree`, custom haxe "bits" like haxe_Log::trace - see: `/lib`) 21 | * Custom C++ generator 22 | * [Messy] "compiler" .hx class to compile build / link generated c++ 23 | * Ability to push to Arduino device ~~(hardcoded to COM3 - needs to change!)~~ 24 | * Ability to start reading from serial com port via hxSerial for program traces ~~(hardcoded to COM3 - needs to change!)~~ 25 | 26 | 27 | Follow Ian Harrigan on: 28 | 29 | - [twitter](https://twitter.com/IanHarrigan1982) 30 | - [github](https://github.com/ianharrigan) 31 | 32 | ## Issues 33 | 34 | If you could point us to the correct direction, create an [issue](https://github.com/ianharrigan/hxArduino/issues). 35 | Even better would be a pull request! -------------------------------------------------------------------------------- /docs/_sidebar.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | * [Home](/) 4 | 5 | * [Haxe](haxe/about.md) 6 | * [Quick install](haxe/quick-install.md) 7 | * [Installation](haxe/installation.md) 8 | * [Code editor](haxe/choosing-a-code-editor.md) 9 | * [Hello world](haxe/hello-world.md) 10 | * [Learn Haxe](haxe/learn-haxe.md) 11 | 12 | * [Getting started](start/getting_started.md) 13 | * [Windows](start/windows.md) 14 | * [OSX](start/osx.md) 15 | * [Linux (needs love)](start/linux.md) 16 | 17 | * How to build 18 | * [options](build/options.md) 19 | * [build](build/build.md) 20 | * [Build hxArduino](build/project.md) 21 | 22 | * Example 23 | * [Blink](example/blink.md) 24 | 25 | * Notes 26 | * [Docsify](notes/docsify.md) 27 | * [Ports](notes/ports.md) 28 | * [Baud](notes/baud.md) 29 | * [Main](notes/main.md) 30 | * [System](notes/system.md) 31 | * [Todo](notes/todo.md) 32 | * [Syntax](notes/syntax.md) 33 | -------------------------------------------------------------------------------- /docs/example/blink.md: -------------------------------------------------------------------------------- 1 | # Basic blink tutorial 2 | 3 | We will not recreate all tutorials form the arduino website. 4 | 5 | But we will use the blink example to get you started: 6 | 7 | 8 | ## Setup 9 | 10 | Besides having a Arduino and a way to connect it to your laptop, you don't need anything else. 11 | 12 | 13 | ## Code 14 | 15 | This is as close as we can get to the orignal code: 16 | 17 | ```haxe 18 | package; 19 | 20 | class Main { 21 | 22 | // the setup function runs once when you press reset or power the board 23 | public function setup() { 24 | // initialize digital pin LED_BUILTIN as an output. 25 | Arduino.pinMode(Arduino.LED_BUILTIN, Arduino.OUTPUT); 26 | } 27 | 28 | // the loop function runs over and over again forever 29 | public function loop() { 30 | Arduino.digitalWrite(Arduino.LED_BUILTIN, Arduino.HIGH); // turn the LED on (HIGH is the voltage level) 31 | Arduino.delay(1000); // wait for a second 32 | Arduino.digitalWrite(Arduino.LED_BUILTIN, Arduino.LOW); // turn the LED off by making the voltage LOW 33 | Arduino.delay(1000); // wait for a second 34 | } 35 | 36 | static function main() { 37 | } 38 | } 39 | ``` 40 | 41 | -------------------------------------------------------------------------------- /docs/haxe/about.md: -------------------------------------------------------------------------------- 1 | # What is Haxe? 2 | 3 | ![Haxe logo](../img/haxe_logo.png) 4 | 5 | 6 | Lets get the Wikipedia description first: 7 | 8 | > Haxe is an open source high-level multi-platform programming language and compiler that can produce applications and source code for many different platforms from a single code-base. 9 | > 10 | > Haxe includes a set of common functionality that is supported across all platforms, such as numeric data types, text, arrays, binary and some common file formats. Haxe also includes platform-specific API for Adobe Flash, C++, PHP and other languages. 11 | > 12 | > Code written in the Haxe language can be source-to-source compiled into ActionScript 3 code, JavaScript programs, Java, C# , C++ standalone applications, Python, PHP, Apache CGI, and Node.js server-side applications. 13 | 14 | 15 | *From [wikipedia](https://en.wikipedia.org/wiki/Haxe)* 16 | 17 | ---- 18 | 19 | And the official description: 20 | 21 | > Haxe consists of a high-level, open source programming language and a compiler. It allows compilation of programs, written using an ECMAScript-oriented syntax, to multiple target languages. Employing proper abstraction, it is possible to maintain a single code-base which compiles to multiple targets. 22 | > 23 | > Haxe is strongly typed but the typing system can be subverted where required. Utilizing type information, the Haxe type system can detect errors at compile-time which would only be noticeable at run-time in the target language. Furthermore, type information can be used by the target generators to generate optimized and robust code. 24 | 25 | 26 | *From [haxe.org - manual](http://haxe.org/manual/introduction-what-is-haxe.html)* 27 | 28 | ----- 29 | 30 | ## History 31 | 32 | A long time ago, there was MTASC, the ActionScript 2 compiler which brought Flash to the entreprise, 33 | and its author, [Nicolas Cannasse](https://twitter.com/ncannasse), decided to create a new open-source 34 | language inspired by ActionScript and ML languages like Ocaml: Haxe. 35 | 36 | Around 2006, Haxe was born, designed to be adapted to a wide variety of targets, including Flash and JavaScript. 37 | 38 | ## Early users 39 | 40 | It was already the most modern compile-to-JS language, but of course a big focus from the author's company 41 | was games, and likewise the initial community using Haxe was certainly oriented into gaming more than web apps. 42 | 43 | Quickly small companies and indie developers wanted to just code everything with Haxe: PHP on the server, 44 | JS for the web interactions, Flash for games, then C++ to look for more performance and freedom in games. 45 | 46 | NME and OpenFl appeared as the first big efforts to reproduce the Flash API for desktop and mobile - people 47 | have started, abusively, assimilating OpenFl with Haxe, while it was just one library among many. 48 | 49 | ## The raise of JavaScript 50 | 51 | JavaScript has taken the world by storm now; people use it for increasingly complex browser apps, but also 52 | for command line and server applications, and even more recently for native apps using react-native. 53 | 54 | Following this trend, users of Haxe-JavaScript have also grown and keep up with the state of the art, 55 | and Haxe developers believe it's a better language for small to huge JavaScript projects. 56 | 57 | A popular language like TypeScript, which appeared much later than Haxe and recently gained a large 58 | following thanks to being closer to ES6 and backed by big corporations, shows that typed languages 59 | are a concern which appeals to JavaScript developers. And while TypeScript is a decent language, it 60 | essentially has the same pros and cons as regular JavaScript and compilation is several orders of 61 | magnitude slower than Haxe for large projects. 62 | 63 | This documentation will hopefully demonstrate how easy it is to use Haxe for JavaScript development. It 64 | may not look as easy as other compile-to-JS to get started but it really doesn't require a big investment 65 | to become familiar with it - and it will make you a better programmer. 66 | 67 | --- 68 | -------------------------------------------------------------------------------- /docs/haxe/choosing-a-code-editor.md: -------------------------------------------------------------------------------- 1 | # Choosing a Code Editor 2 | 3 | Once Haxe has been [installed](installation.md) (yes you should do that first!). It is helpful to choose an integrated development environment (IDE), with good support for Haxe development. 4 | 5 | Although you can write code using even a simple text editor. 6 | A quality IDE can provide: 7 | 8 | - code completion (code hints) 9 | - shortcuts to build and test your projects 10 | - and other tools to give you a great coding experience. 11 | 12 | 13 | ## Visual Studio Code 14 | 15 | Code is the recommended editor to get started with Haxe, and is the current main effort from the Haxe Foundation. 16 | 17 | ![Visual Studio Code](https://haxe.org/img/ide/vscode.gif) 18 | 19 | [Visual Studio Code](https://code.visualstudio.com/) Build and debug modern web and cloud applications. 20 | 21 | Code is free and open-source, and cross platform - Linux, Mac OSX, and Windows. 22 | 23 | 24 | ## HaxeDevelop 25 | 26 | ![](http://haxedevelop.org/img/haxedevelop-interface.jpg) 27 | 28 | [HaxeDevelop](http://www.haxedevelop.org) is one of the strongest IDEs for large scale Haxe development. 29 | If you are a Windows user (and perhaps if you are not), we recommend that you try HaxeDevelop first. 30 | 31 | HaxeDevelop is free and open-source. 32 | 33 | 34 | ## IntelliJ IDEA 35 | 36 | ![](https://www.jetbrains.com/idea/img/screenshots/idea_overview_5_1.png) 37 | 38 | [IntelliJ IDEA](https://www.jetbrains.com/idea/) is primarily marketed as a Java IDE. But it has a growing support within the Haxe community, and is prefered by large teams. The full edition and the free community edition, support the open-source [Haxe plugin](https://plugins.jetbrains.com/plugin/6873?pr=idea). 39 | 40 | 41 | ## Other Choices 42 | 43 | There are other code editors to choose from, include vim and up-and-coming Haxe-based editors. You can read more at [http://haxe.org/documentation/introduction/editors-and-ides.html](http://haxe.org/documentation/introduction/editors-and-ides.html) 44 | 45 | 46 | ## Summary 47 | 48 | | Name | Platform | Price | License | Plugin | 49 | | ---- | ---- | ---- | ---- | ---- | ---- | 50 | | VSCode | Windows, Mac, Linux | Free | ? | [Haxe Extension Pack ](https://marketplace.visualstudio.com/items?itemName=vshaxe.haxe-extension-pack) | 51 | | HaxeDevelop | Windows | Free | Open Source | | 52 | | IntelliJ IDEA | Windows, Mac, Linux | Free | Apache License 2.0 | [Haxe Support](http://plugins.jetbrains.com/plugin/6873?pr=idea) | 53 | 54 | 55 | *Some of this information is directly from [Openfl documentation](http://www.openfl.org/learn/resources/choosing-a-code-editor/)* 56 | -------------------------------------------------------------------------------- /docs/haxe/code/Test.hx: -------------------------------------------------------------------------------- 1 | class Test { 2 | static function main() { 3 | trace("Hello World !"); 4 | } 5 | } -------------------------------------------------------------------------------- /docs/haxe/code/build.hxml: -------------------------------------------------------------------------------- 1 | -js test.js 2 | -main Test -------------------------------------------------------------------------------- /docs/haxe/code/test.html: -------------------------------------------------------------------------------- 1 | 2 | Haxe JS 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/haxe/code/test.js: -------------------------------------------------------------------------------- 1 | // Generated by Haxe 3.4.7 2 | (function () { "use strict"; 3 | var Test = function() { }; 4 | Test.main = function() { 5 | console.log("Hello World !"); 6 | }; 7 | Test.main(); 8 | })(); 9 | -------------------------------------------------------------------------------- /docs/haxe/hello-world.md: -------------------------------------------------------------------------------- 1 | # Hello world 2 | 3 | ![](../img/helloworld.png) 4 | 5 | Developing JavaScript code is easy with Haxe. Let's see our first HelloWorld example : 6 | 7 | ```haxe 8 | class Test { 9 | static function main() { 10 | trace("Hello World !"); 11 | } 12 | } 13 | ``` 14 | 15 | Put this class into a file named `Test.hx` and create the file `compile.hxml` in the same directory with the following content: 16 | 17 | ``` 18 | -js test.js 19 | -main Test 20 | ``` 21 | 22 | To compile open you terminal and type: 23 | 24 | cd 25 | 26 | And drag the folder where you saved the files, into the terminal. 27 | It will look something like this: 28 | 29 | cd /path/to/folder/ 30 | 31 | Press enter and type: 32 | 33 | haxe compile.hxml 34 | 35 | If an error occurs, the terminal will display that. 36 | If everything went smoothly like it should, this will produce a `test.js` file that can be embedded into an HTML page such as this one : 37 | 38 | ```html 39 | 40 | Haxe JS 41 | 42 | 43 | 44 | 45 | 46 | 47 | ``` 48 | 49 | 1. Put this code into a `test.html` file. 50 | 2. Open it with your browser (like Google Chrome) 51 | 3. It will display **Hello World** in your Console. 52 | 4. (Google Chrome > Hamburger menu > More Tools > Developers tools) 53 | 54 | 55 | ## try.haxe 56 | 57 | If you want to experiment with this code, you can do that without installing Haxe. 58 | 59 | Below you can see and try the same example code at [try.haxe.org](https://try.haxe.org/) without installing Haxe. 60 | 61 | 64 | 65 | 66 | *Based upon [old.haxe.org - manual](http://old.haxe.org/doc/start/js)* 67 | -------------------------------------------------------------------------------- /docs/haxe/index.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ianharrigan/hxArduino/e831388db25159ae57b7773905f14c7d6886c5c4/docs/haxe/index.md -------------------------------------------------------------------------------- /docs/haxe/installation.md: -------------------------------------------------------------------------------- 1 | # Installing Haxe 2 | 3 | 4 | ![](../img/install.jpg) 5 | 6 | 7 | First, you will need to install Haxe (Neko and Haxelib). 8 | There are a couple ways to install Haxe: 9 | 10 | * Get the [installer](#haxe) from [haxe.org](http://haxe.org/download/) (original) 11 | * Use [NPM](#npm) 12 | * Use [Homebrew](#brew) 13 | * Use [Chocolatey](#chocolatey) 14 | 15 | 16 | Although all the installation methods _should_ work. I have use the original installer from haxe.org, and didn't try the other methods. 17 | 18 | My suggestion would be to use that one! 19 | 20 | 21 | 22 | ## Installer (original) from haxe.org 23 | 24 | You can find installers and binaries for Windows, OS X and Linux on [http://haxe.org/download/](http://haxe.org/download/). 25 | 26 | 27 | 28 | ## Install with NPM (node) 29 | 30 | Before you can install Haxe, you have to install Node.js (and thus NPM). 31 | Installing Haxe with NPM makes sense if you have NPM installed already. 32 | 33 | But here is the link to install Node.js: [https://nodejs.org/](https://nodejs.org/) 34 | 35 | After installation use: 36 | 37 | npm install -g haxe 38 | 39 | *[read more about Haxe at NPM](https://www.npmjs.com/package/haxe)* 40 | AND check out all the [Haxe related projects](https://www.npmjs.com/browse/keyword/haxe) on NPM. 41 | 42 | 43 | ## Install with Homebrew 44 | 45 | Same as with Node.js, you probably want to use Homebrew if you have this already installed. 46 | Worth mentioning: this works on OS X. 47 | 48 | Visit [http://brew.sh/](http://brew.sh/) to get instruction how to install Homebrew. 49 | 50 | After installation use: (install latest from git with --HEAD) 51 | 52 | brew install haxe --HEAD 53 | 54 | 55 | 56 | ## Install with chocolatey 57 | 58 | This is a Windows install method. You can get your Chocolatey install instructions from [chocolatey.org](https://chocolatey.org/) 59 | 60 | After installation use: 61 | 62 | choco install haxe 63 | 64 | --- -------------------------------------------------------------------------------- /docs/haxe/learn-haxe.md: -------------------------------------------------------------------------------- 1 | # Learn Haxe 2 | 3 | ![](http://haxe.org/img/targets/all-targets.svg) 4 | 5 | 6 | Okay that is a little bit to much to ask for now. 7 | Instead me trying to explain it, I will give you some places you can go. 8 | 9 | 10 | ## Learn X in Y minutes 11 | 12 | **I love this one!** 13 | 14 | > Take a whirlwind tour of your next favorite language. Community-driven! 15 | 16 | Learn in code: Learn Haxe 3 in 15 minutes. 17 | 18 | [learn x in y minutes : Haxe](http://learnxinyminutes.com/docs/haxe/) 19 | 20 | 21 | ## haxe.org 22 | 23 | Can't miss this one, it's the mother ship 24 | 25 | [haxe.org - documentation](http://haxe.org/documentation/introduction/) 26 | 27 | 28 | ## Haxe API documentation 29 | 30 | Find the documentation here: [http://api.haxe.org/](http://api.haxe.org/) 31 | 32 | 33 | ## Haxe Manual 34 | 35 | Same idea as this documentation (not with `.md`- but `.tex`-files). But more in-depth into coding with Haxe (wip): the [HaxeManual](https://github.com/HaxeFoundation/HaxeManual). 36 | Download the [pdf here](https://github.com/HaxeFoundation/HaxeManual/raw/master/HaxeManual/HaxeManual.pdf) 37 | 38 | 39 | ## Try Haxe 40 | 41 | Not a place to learn, but to **try out** without installing Haxe. 42 | [Try Haxe!](https://try.haxe.org/) 43 | 44 | 45 | ## Haxe Code Cookbook 46 | 47 | A lot of nice example in different categories: 48 | 49 | - Beginner 50 | - Abstract types 51 | - Compilation 52 | - Data structures 53 | - Design patterns 54 | - Functional Programming 55 | - Macros 56 | - Principles 57 | - Other 58 | 59 | > Easy to read Haxe coding examples. 60 | 61 | [Haxe Code Cookbook](http://code.haxe.org/) 62 | 63 | 64 | ## Video 65 | 66 | Videos that could help you on your way 67 | 68 | #### Haxe for Absolute Beginners: Getting Started 69 | 70 | [![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/d0Kc4j6qFAA/0.jpg)](http://www.youtube.com/watch?v=d0Kc4j6qFAA) 71 | 72 | > This is a tutorial series starting from the very beginning on explaining exactly what Haxe is, how you can get started and understanding everything it has to offer us. 73 | 74 | #### Haxe Tutorial 1 Getting Set Up 75 | 76 | [![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/EAn29Xeiz4w/0.jpg)](http://www.youtube.com/watch?v=EAn29Xeiz4w) 77 | 78 | 79 | 80 | #### "10 years of Haxe / 10 things I like" by Nicolas Cannasse 81 | 82 | [![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/sM8VhotrIJs/0.jpg)](http://www.youtube.com/watch?v=sM8VhotrIJs) 83 | 84 | > Nicolas Cannasse shares with us his 10 things for the 10 years Haxe's anniversary in his talk “10 Years of Haxe / 10 Things I like”. He presents the latest changes that were introduced in Haxe as well as Haxe Foundation plans for the future. 85 | 86 | 87 | #### "A walk-through of Haxe JS Kit" by Clément Charmet 88 | 89 | 90 | [![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/YJ3IvE6qCEA/0.jpg)](http://www.youtube.com/watch?v=YJ3IvE6qCEA) 91 | 92 | > Talk description: in this talk “A walk-through of Haxe JS Kit”, Clément Charmet demonstrates the main features of Haxe JS Kit, and through them, the huge benefits of using Haxe over alternatives such as Typescript to "just" target JavaScript. 93 | 94 | 95 | #### "NPM, Haxe at the heart of JavaScript ecosystem" by David Mouton 96 | 97 | 98 | [![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/YgbxqFx9qak/0.jpg)](http://www.youtube.com/watch?v=YgbxqFx9qak) 99 | 100 | > Talk description: David Mouton presents “NPM, Haxe at the heart of JavaScript ecosystem”. JavaScript ecosystem for web app development is well implanted and NPM is at the centre of it. Coffeescript and Typescript are perfectly integrated and have offered a real alternative to full JavaScript development. For almost a year now, Haxe has constituted a third alternative in this ecosystem. 101 | 102 | 103 | #### Haxe, a language that compiles to JS 104 | 105 | [![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/7YNR9HAm6D0/0.jpg)](https://www.youtube.com/watch?v=7YNR9HAm6D0) 106 | 107 | > Nowadays there are a lot of languages that are able to compile to JS (e.g. Dart, TypeScript, Java/GWT etc.). One that is less well-known, but will surely blow your mind, is Haxe. It is one of the earliest languages that target JS (since 2006). It is a statically-typed language with ECMAScript like syntax. 108 | 109 | 110 | #### Peter Štefček (Pixel Federation): Open-source Lang. Haxe for Dev. of Platform-independent Apps 111 | 112 | [![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/CupIdO-GpVg/0.jpg)](https://www.youtube.com/watch?v=CupIdO-GpVg) 113 | 114 | > Introduction to open-source programming language Haxe, what it can offer and how you can use it to target multiple platforms. 115 | > 116 | > Will talk about what is Haxe and how it can help you to start develop multiplatform applications with ease. How you can leverage existing programming skills and even libraries from other languages like Javascript and can run across Flash, Javascript, C++, Android, iOS and many more. 117 | > 118 | >Showcase of Haxe's compiler to target native platforms as well as languages or VM's, and why it's a safe bet for a future-proof codebase. Examples using the language that can get you started. 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | ## Other links, perhaps worth looking into 127 | 128 | Could be old and outdated, haven't investigated it thourough. 129 | 130 | * [http://haxelearning.wikispaces.com/](http://haxelearning.wikispaces.com/) 131 | * [http://haxe.us/haxe_tutorial.html](http://haxe.us/haxe_tutorial.html) 132 | -------------------------------------------------------------------------------- /docs/haxe/quick-install.md: -------------------------------------------------------------------------------- 1 | # Quick install 2 | 3 | This tutorial is for the TL;DR crowd... 4 | You just want to get started ... right! 5 | 6 | ![](../img/tldr.gif) 7 | 8 | ## Step 0: You have joined an elite Haxe force! 9 | 10 | You are cooler then a polar bear! 11 | 12 | ## Step 1: Install Haxe 13 | 14 | You can find installers and binaries for Windows, OS X and Linux on [http://haxe.org/download/](http://haxe.org/download/). 15 | 16 | - Download 17 | - And install 18 | 19 | ## Step 2: Install Editor 20 | 21 | You need an editor, lets install **Visual Studio Code** 22 | 23 | ![Visual Studio Code](https://haxe.org/img/ide/vscode.gif) 24 | 25 | On the homepage of [Visual Studio Code](https://code.visualstudio.com/) find the button for your OS. 26 | 27 | - Download 28 | - And install 29 | 30 | ## Step 3: Install VSCode - Haxe Extension Pack 31 | 32 | To get VSCode working with Haxe you should install the "Haxe Extension Pack" 33 | 34 | ([Haxe Extension Pack ](https://marketplace.visualstudio.com/items?itemName=vshaxe.haxe-extension-pack)) 35 | 36 | - Launch VS Code 37 | - Quick Open (Ctrl+P / ⌘+P) 38 | - Paste the following command: `ext install haxe-extension-pack` 39 | - And type enter 40 | 41 | It currently contains 3 extensions 42 | 43 | - Haxe ([Haxe Support for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=nadako.vshaxe)) 44 | - Haxe Debug ([Haxe Debug for flash target](https://marketplace.visualstudio.com/items?itemName=vshaxe.haxe-debug)) 45 | - codedox ([JSDoc style comments](https://marketplace.visualstudio.com/items?itemName=wiggin77.codedox)) 46 | 47 | But that might become more in the future! 48 | 49 | ## Step 4 (extra): Install haxelib libraries 50 | 51 | This is not necessary but something you eventually need to do. 52 | 53 | - Open `terminal` 54 | - Copy and past the following 55 | 56 | ``` 57 | haxelib install hxnodejs 58 | haxelib git js-kit https://github.com/clemos/haxe-js-kit.git haxelib 59 | haxelib install markdown 60 | haxelib install msignal 61 | ``` 62 | 63 | ## Step 5 (Extra): Install NPM/Node.js 64 | 65 | Download Node.js: get your version here: [https://nodejs.org/](https://nodejs.org/) 66 | 67 | - Download 68 | - And install 69 | 70 | Now you have access to NPM. 71 | 72 | - Open `terminal` 73 | - Copy and paste the following (and see current NPM version) 74 | 75 | ``` 76 | npm -v 77 | ``` 78 | 79 | --- 80 | -------------------------------------------------------------------------------- /docs/img/Arduino_Logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 56 | 59 | 60 | 65 | 68 | 72 | 73 | 78 | 79 | 80 | 81 | 88 | 91 | 95 | 96 | 97 | 107 | 111 | 115 | 119 | 123 | 127 | 131 | 135 | 139 | 140 | 141 | 146 | 150 | 154 | 155 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /docs/img/Haxe_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | image/svg+xmlHaxe Foundation -------------------------------------------------------------------------------- /docs/img/arduino_haxe_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ianharrigan/hxArduino/e831388db25159ae57b7773905f14c7d6886c5c4/docs/img/arduino_haxe_logo.png -------------------------------------------------------------------------------- /docs/img/arduino_haxe_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | 41 | 42 | 43 | 44 | 45 | 46 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 58 | 59 | 60 | 61 | 62 | 64 | 69 | 74 | 78 | 79 | 81 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /docs/img/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ianharrigan/hxArduino/e831388db25159ae57b7773905f14c7d6886c5c4/docs/img/banner.png -------------------------------------------------------------------------------- /docs/img/haxe_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ianharrigan/hxArduino/e831388db25159ae57b7773905f14c7d6886c5c4/docs/img/haxe_logo.png -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /docs/notes/baud.md: -------------------------------------------------------------------------------- 1 | # Baud 2 | 3 | The data rate in bits per second (baud) for serial data transmission. 4 | 5 | For communicating with the computer, use one of these rates: 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, or 115200. 6 | 7 | ## fixed baud rate 8 | 9 | currently this project has a fixed baud rate: `115200` 10 | 11 | ## Code 12 | 13 | Simple example: 14 | 15 | ```haxe 16 | package; 17 | 18 | class Main { 19 | public function setup() { 20 | Serial.begin(115200); // opens serial port, sets data rate to 115200 bps 21 | } 22 | 23 | public function loop() { 24 | Serial.println('FOO'); 25 | Arduino.delay(1000); 26 | Serial.println('BAR'); 27 | Arduino.delay(1000); 28 | } 29 | 30 | static function main() { 31 | } 32 | } 33 | ``` -------------------------------------------------------------------------------- /docs/notes/docsify.md: -------------------------------------------------------------------------------- 1 | # docsify 2 | 3 | We use docsify 4 | 5 | 6 | 7 | ``` 8 | docsify serve docs 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/notes/main.md: -------------------------------------------------------------------------------- 1 | # main.cpp 2 | 3 | * main.cpp (not generated) makes assumption that there is a `Main.h` and a `Main` c++ class in entry point, eg: 4 | 5 | ```cpp 6 | #include 7 | #include "Main.h" 8 | 9 | ... 10 | 11 | int main(void) 12 | { 13 | ... 14 | Serial.begin(115200); 15 | 16 | Main main; 17 | main.setup(); 18 | 19 | for (;;) { 20 | main.loop(); 21 | ... 22 | } 23 | 24 | return 0; 25 | } 26 | ``` 27 | 28 | Get your empty template here: 29 | 30 | ```haxe 31 | package; 32 | 33 | class Main { 34 | 35 | // the setup routine runs once when you press reset: 36 | public function setup() { 37 | } 38 | 39 | // the loop routine runs over and over again forever: 40 | public function loop() { 41 | } 42 | 43 | static function main() { 44 | } 45 | } 46 | ``` 47 | -------------------------------------------------------------------------------- /docs/notes/ports.md: -------------------------------------------------------------------------------- 1 | # Ports 2 | 3 | 4 | Select the serial device of the Arduino board from the Tools | Serial Port menu. On Windows, this should be `COM1` or `COM2` for a serial Arduino board, or `COM3`, `COM4`, or `COM5` for a USB board. 5 | 6 | On the Mac, this should be something like `/dev/cu.usbserial-1B1` for a USB board, or something like `/dev/cu.USA19QW1b1P1.1` if using a Keyspan adapter with a serial board (other USB-to-serial adapters use different names). 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /docs/notes/syntax.md: -------------------------------------------------------------------------------- 1 | # Syntax not implemented yet 2 | 3 | Fair amount of syntax not yet implemented in generator (eg: loops) -------------------------------------------------------------------------------- /docs/notes/system.md: -------------------------------------------------------------------------------- 1 | # system 2 | 3 | * Undoubtedly assumptions made that are specific to my system (paths, com ports, etc - needs ironing out) 4 | * Only tested on windows, and a single windows box (mine!) -------------------------------------------------------------------------------- /docs/notes/todo.md: -------------------------------------------------------------------------------- 1 | # Todo 2 | 3 | * Currently skips alot of haxe "internal" classes (no point in trying to generated them till generator is at least all wired up) -------------------------------------------------------------------------------- /docs/start/getting_started.md: -------------------------------------------------------------------------------- 1 | # Getting started 2 | 3 | Please remember this is work in progress, and this documentation can change and/or not even reflect the current state. 4 | 5 | But also remember, nobody writes documentation just to send you on a wild goose chase. 6 | 7 | Also this document assumes a lot: 8 | 9 | - knowledge of Haxe 10 | - knowledge of Arduino 11 | - how to use a terminal 12 | - possession of a Arduino and the correct cables to connect 13 | - probably a lot more... 14 | 15 | ## Step 0. 16 | 17 | I am going to state the obvious here: 18 | 19 | - [Install Haxe](https://haxe.org/download) 20 | - [Install VS Code](https://code.visualstudio.com) 21 | - [Install the Arduino IDE](https://www.arduino.cc/en/Main/Software) 22 | 23 | 24 | 25 | ## Step 1. 26 | 27 | You need to install/download this project: 28 | 29 | #### Methode 1: 30 | 31 | Use git to download this project: 32 | 33 | `cd` to correct folder and check out project 34 | 35 | ```bash 36 | cd path/to/folder 37 | git checkout https://github.com/ianharrigan/hxArduino.git 38 | ``` 39 | 40 | #### Methode 2: 41 | 42 | Use haxelib to download this project: 43 | 44 | ```bash 45 | haxelib git hxArduino https://github.com/ianharrigan/hxArduino.git 46 | ``` 47 | 48 | 49 | ## Step 2. 50 | 51 | You can use this git repos as a development directory: 52 | 53 | ```bash 54 | haxelib dev hxArduino path/to/folder 55 | ``` 56 | 57 | ## Step 3. 58 | 59 | 60 | This project uses an extra lib "[hxSerial](https://lib.haxe.org/p/hxSerial/)", which can be install via Haxelib (the package manager for the Haxe Toolkit). 61 | 62 | `haxelib install hxSerial` 63 | 64 | or 65 | 66 | `haxelib install build.hxml` 67 | 68 | ## Step 4. 69 | 70 | Set Environment variable, this is platform specific: 71 | 72 | - set `ARDUINO_HOME` 73 | - optional set `ARDUINO_PORT` 74 | 75 | Check out platform specific information: 76 | 77 | * [Windows](start/windows.md?id=environment-variable) 78 | * [OSX](start/osx.md?id=environment-variable) 79 | * [Linux (needs love)](start/linux.md?id=environment-variable) 80 | 81 | 82 | ## Step 5. 83 | 84 | Create a project you want to upload to your Arduino. 85 | 86 | Check the [Example folder](https://github.com/ianharrigan/hxArduino/tree/master/examples) 87 | 88 | Do you need more info, check out [Blink Example](example/blink.md) 89 | 90 | 91 | ## Step 6. 92 | 93 | > Run commands 94 | 95 | 96 | Install Arduino code on device. 97 | `haxelib run hxArduino --install -port /dev/cu.usbmodem14101` 98 | 99 | Monitor ports. 100 | `haxelib run hxArduino --monitor -port /dev/cu.usbmodem14101` 101 | 102 | Install and monitor. 103 | `haxelib run hxArduino --test -port /dev/cu.usbmodem14101` 104 | 105 | Get list of connected ports. 106 | `haxelib run hxArduino --portlist` 107 | 108 | Show this help message and exit. 109 | `haxelib run hxArduino --help` 110 | 111 | 112 | 113 | ## ??? 114 | 115 | 116 | * `haxe -lib hxArduino -cp src -neko dummy.n -main Main` 117 | * (Need to use neko dummy output for now - not entirely sure why) 118 | * `haxelib run hxArduino test C:\Temp\temp2\bin\generated` 119 | * Makes COM port assumption (needs to change!) 120 | -------------------------------------------------------------------------------- /docs/start/linux.md: -------------------------------------------------------------------------------- 1 | # hxArduino on Linux 2 | 3 | Make sure you followed the [Getting Started](getting_started.md) instructions first. 4 | 5 | **This needs more love** 6 | 7 | 8 | ## Environment variable 9 | 10 | **Yes! you guessed it, we don't have a clue** 11 | 12 | If you could point us to the correct direction, create an [issue](https://github.com/ianharrigan/hxArduino/issues). 13 | Even better would be a pull request! 14 | 15 | ## Find Arduino Port 16 | 17 | Find Port Number on Linux 18 | Open terminal and type: `ls /dev/tty*.` 19 | 20 | Note the port number listed for `/dev/ttyUSB*` or `/dev/ttyACM*`. The port number is represented with `*` here. 21 | 22 | For example: `/dev/ttyUSB0`. 23 | 24 | 25 | Or use build in tool: 26 | 27 | `haxelib run hxArduino --portlist` 28 | -------------------------------------------------------------------------------- /docs/start/osx.md: -------------------------------------------------------------------------------- 1 | # hxArduino on OSX 2 | 3 | Make sure you followed the [Getting Started](getting_started.md) instructions first. 4 | 5 | ## Environment variable 6 | 7 | Normally if you follow the install instructions, you will install Arduino into `~/Applications` folder 8 | 9 | If you did that, this app will run smooth! 10 | 11 | 12 | 13 | Otherwise you need to set some environment variable 14 | 15 | ```bash 16 | ARDUINO_HOME=/NotApplications/Arduino.app/Contents/Java 17 | ``` 18 | (default: `/Applications/Arduino.app/Contents/Java`) 19 | 20 | You can also set the port of the serial device 21 | 22 | ```bash 23 | ARDUINO_PORT=/dev/cu.usbmodem14101 24 | ``` 25 | (default: `COM3` which will never work!) 26 | 27 | Forgot how to? Check [How to set environment variable](osx.md?id=how-to-set-environment-variable) 28 | 29 | 30 | ## Find Arduino Port 31 | 32 | Find Port Number on Macintosh 33 | Open terminal and type: `ls /dev/*`. 34 | 35 | Note the port number listed for `/dev/tty.usbmodem*` or `/dev/tty.usbserial*`. The port number is represented with `*` here. 36 | 37 | For example: `/dev/ttyUSB0`. 38 | 39 | Or use build in tool: 40 | 41 | `haxelib run hxArduino --portlist` 42 | 43 | Possible answer **without** an Arduino connected to your computer: 44 | 45 | ```bash 46 | Port list: [/dev/cu.Bluetooth-Incoming-Port,/dev/tty.Bluetooth-Incoming-Port] 47 | - port: /dev/cu.Bluetooth-Incoming-Port, available: 0, 48 | - port: /dev/tty.Bluetooth-Incoming-Port, available: 0, null 49 | Your guess is as good as mine; try to disconnect and run this command again and see the differences 50 | ``` 51 | 52 | Possible answer **with** an Arduino connected to your computer: 53 | 54 | ```bash 55 | Port list: [/dev/cu.Bluetooth-Incoming-Port,/dev/tty.Bluetooth-Incoming-Port,/dev/cu.usbmodem14101,/dev/tty.usbmodem14101] 56 | - port: /dev/cu.Bluetooth-Incoming-Port, available: 0, 57 | - port: /dev/tty.Bluetooth-Incoming-Port, available: 0, null 58 | - port: /dev/cu.usbmodem14101, available: 11, 59 | - port: /dev/tty.usbmodem14101, available: 0, null 60 | Use: haxelib run hxArduino --test -port /dev/cu.usbmodem14101 61 | ``` 62 | 63 | ## How to set environment variable 64 | 65 | #### Methode 1: 66 | 67 | To set an environment variable, enter the following command: 68 | 69 | ```bash 70 | launchctl setenv variable "value" 71 | ``` 72 | 73 | To find out if an environment variable is set, use the following command: 74 | 75 | ```bash 76 | launchctl getenv variable 77 | ``` 78 | 79 | To clear an environment variable, use the following command: 80 | 81 | ```bash 82 | launchctl unsetenv variable 83 | ``` 84 | 85 | #### Methode 2: 86 | 87 | 88 | Write bash_profile 89 | 90 | 91 | ```bash 92 | ~/.bash_profile 93 | nano .bash_profile 94 | export ARDUINO_HOME=/Applications/Arduino.app/Contents/Java 95 | export ARDUINO_PORT=/dev/cu.usbmodem14101 96 | ``` 97 | 98 | Or just test it: 99 | 100 | ```bash 101 | export ARDUINO_HOME=/Applications/Arduino.app/Contents/Java 102 | export ARDUINO_PORT=/dev/cu.usbmodem14101 103 | ``` 104 | 105 | 106 | 107 | Source: 108 | 109 | - 110 | - 111 | 112 | 113 | -------------------------------------------------------------------------------- /docs/start/windows.md: -------------------------------------------------------------------------------- 1 | # hxArduino on Windows 2 | 3 | Make sure you followed the [Getting Started](getting_started.md) instructions first. 4 | 5 | ## Environment variable 6 | 7 | To get the project working you need to set some environment variable 8 | 9 | ```bash 10 | ARDUINO_HOME=C:\\path\\to\\arduino 11 | ``` 12 | (default: `C:\\PROGRA~2\\Arduino`) 13 | 14 | You can also set the port of the serial device 15 | 16 | ```bash 17 | ARDUINO_PORT=COM6 18 | ``` 19 | (default: `COM3`) 20 | 21 | 22 | ## Find Arduino Port 23 | 24 | Find Port Number on Windows 25 | 26 | - Open Device Manager, and expand the Ports (COM & LPT) list. 27 | - Note the number on the USB Serial Port. 28 | 29 | 30 | Or use build in tool: 31 | 32 | `haxelib run hxArduino --portlist` 33 | 34 | -------------------------------------------------------------------------------- /examples/01-blink/01-blink.hxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /examples/01-blink/build.hxml: -------------------------------------------------------------------------------- 1 | -cp src 2 | 3 | -lib hxArduino 4 | 5 | --no-output 6 | 7 | -main Main 8 | 9 | -------------------------------------------------------------------------------- /examples/01-blink/src/Main.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | class Main { 4 | public function setup() { 5 | Arduino.pinMode(Arduino.LED_BUILTIN, Arduino.OUTPUT); 6 | Serial.begin(115200); 7 | } 8 | 9 | public function loop() { 10 | Arduino.digitalWrite(Arduino.LED_BUILTIN, Arduino.HIGH); 11 | 12 | Serial.println('high'); 13 | 14 | Arduino.delay(1000); 15 | 16 | Arduino.digitalWrite(Arduino.LED_BUILTIN, Arduino.LOW); 17 | 18 | Serial.println('low'); 19 | 20 | Arduino.delay(1000); 21 | } 22 | 23 | static function main() { 24 | } 25 | } -------------------------------------------------------------------------------- /examples/02-digital-input/02-digital-input.hxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /examples/02-digital-input/build.hxml: -------------------------------------------------------------------------------- 1 | -cp src 2 | 3 | -lib hxArduino 4 | 5 | --no-output 6 | 7 | -main Main 8 | 9 | -------------------------------------------------------------------------------- /examples/02-digital-input/src/Main.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | class Main { 4 | public function setup() { 5 | Arduino.pinMode(Arduino.LED_BUILTIN, Arduino.OUTPUT); 6 | Arduino.pinMode(2, Arduino.INPUT); 7 | Arduino.pinMode(3, Arduino.INPUT); 8 | } 9 | 10 | public function loop() { 11 | var pin2 = Arduino.digitalRead(2); 12 | 13 | if (pin2 == Arduino.HIGH) { 14 | Arduino.digitalWrite(Arduino.LED_BUILTIN, Arduino.HIGH); 15 | } 16 | // TODO: no if / else (yet!) 17 | if (pin2 == Arduino.LOW) { 18 | Arduino.digitalWrite(Arduino.LED_BUILTIN, Arduino.LOW); 19 | } 20 | 21 | Arduino.delay(1000); 22 | 23 | var pin3 = Arduino.digitalRead(3); 24 | Arduino.digitalWrite(Arduino.LED_BUILTIN, pin3); 25 | 26 | Arduino.delay(1000); 27 | } 28 | 29 | static function main() { 30 | } 31 | } -------------------------------------------------------------------------------- /examples/03-arrays-loops/03-arrays-loops.hxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /examples/03-arrays-loops/build.hxml: -------------------------------------------------------------------------------- 1 | -cp src 2 | 3 | -lib hxArduino 4 | 5 | --no-output 6 | 7 | -main Main 8 | 9 | -------------------------------------------------------------------------------- /examples/03-arrays-loops/src/Main.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | class Main { 4 | public function setup() { 5 | Arduino.pinMode(Arduino.LED_BUILTIN, Arduino.OUTPUT); 6 | } 7 | 8 | public function loop() { 9 | var arr = [Arduino.HIGH, Arduino.LOW, Arduino.HIGH, Arduino.LOW, Arduino.HIGH, Arduino.LOW, Arduino.HIGH]; 10 | for (a in arr) { 11 | Arduino.digitalWrite(Arduino.LED_BUILTIN, a); 12 | Arduino.delay(1000); 13 | } 14 | } 15 | 16 | static function main() { 17 | } 18 | } -------------------------------------------------------------------------------- /examples/04-objects-heap/04-objects-heap.hxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /examples/04-objects-heap/build.hxml: -------------------------------------------------------------------------------- 1 | -cp src 2 | 3 | -lib hxArduino 4 | 5 | --no-output 6 | 7 | -main Main 8 | 9 | -------------------------------------------------------------------------------- /examples/04-objects-heap/src/Main.hx: -------------------------------------------------------------------------------- 1 | package; 2 | import test.Test1; 3 | import test.Test2; 4 | 5 | class Main { 6 | private var _test1:Test1 = new Test1(); 7 | 8 | public function setup() { 9 | Arduino.pinMode(Arduino.LED_BUILTIN, Arduino.OUTPUT); 10 | } 11 | 12 | public function loop() { 13 | var test2:Test2 = new Test2(); 14 | test2.setViaProxy(_test1, 1000); 15 | 16 | Arduino.digitalWrite(Arduino.LED_BUILTIN, Arduino.HIGH); 17 | 18 | Arduino.delay(_test1.get()); 19 | 20 | Arduino.digitalWrite(Arduino.LED_BUILTIN, Arduino.LOW); 21 | 22 | Arduino.delay(_test1.get()); 23 | } 24 | 25 | static function main() { 26 | } 27 | } -------------------------------------------------------------------------------- /examples/04-objects-heap/src/test/Test1.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | class Test1 { 4 | private var _delay:Int = 100; 5 | 6 | public function new() { 7 | } 8 | 9 | public function get():Int { 10 | return _delay; 11 | } 12 | 13 | public function set(value:Int) { 14 | _delay = value; 15 | } 16 | } -------------------------------------------------------------------------------- /examples/04-objects-heap/src/test/Test2.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | class Test2 { 4 | public function new() { 5 | } 6 | 7 | public function setViaProxy(test1:Test1, value:Int) { 8 | test1.set(value); 9 | } 10 | } -------------------------------------------------------------------------------- /examples/05-objects-stack/05-objects-stack.hxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /examples/05-objects-stack/build.hxml: -------------------------------------------------------------------------------- 1 | -cp src 2 | 3 | -lib hxArduino 4 | 5 | --no-output 6 | 7 | -main Main 8 | 9 | -------------------------------------------------------------------------------- /examples/05-objects-stack/src/Main.hx: -------------------------------------------------------------------------------- 1 | package; 2 | import test.Test1; 3 | import test.Test2; 4 | 5 | class Main { 6 | private var _test1:Test1 = new Test1(); 7 | 8 | public function setup() { 9 | Arduino.pinMode(Arduino.LED_BUILTIN, Arduino.OUTPUT); 10 | } 11 | 12 | public function loop() { 13 | var test2:Test2 = new Test2(); 14 | test2.setViaProxy(_test1, 1000); 15 | 16 | Arduino.digitalWrite(Arduino.LED_BUILTIN, Arduino.HIGH); 17 | 18 | Arduino.delay(_test1.get()); 19 | 20 | Arduino.digitalWrite(Arduino.LED_BUILTIN, Arduino.LOW); 21 | 22 | Arduino.delay(_test1.get()); 23 | } 24 | 25 | static function main() { 26 | } 27 | } -------------------------------------------------------------------------------- /examples/05-objects-stack/src/test/Test1.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | @:stackOnly 4 | class Test1 { 5 | private var _delay:Int = 100; 6 | 7 | public function new() { 8 | } 9 | 10 | public function get():Int { 11 | return _delay; 12 | } 13 | 14 | public function set(value:Int) { 15 | _delay = value; 16 | } 17 | } -------------------------------------------------------------------------------- /examples/05-objects-stack/src/test/Test2.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | @:stackOnly 4 | class Test2 { 5 | public function new() { 6 | } 7 | 8 | public function setViaProxy(test1:Test1, value:Int) { 9 | test1.set(value); 10 | } 11 | } -------------------------------------------------------------------------------- /examples/06-advanced-type-objects/06-advanced-type-objects.hxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /examples/06-advanced-type-objects/build.hxml: -------------------------------------------------------------------------------- 1 | -cp src 2 | 3 | -lib hxArduino 4 | 5 | --no-output 6 | 7 | -main Main 8 | 9 | -------------------------------------------------------------------------------- /examples/06-advanced-type-objects/src/Main.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | import foo.Varianse.ChildNo1; 4 | import foo.Varianse.ChildNo2; 5 | import foo.Varianse.Base; 6 | import foo.*; 7 | 8 | using foo.Extender.IntExtender; 9 | 10 | class Main { 11 | public function setup() { 12 | 13 | /* using abstract type */ 14 | { 15 | var a1 = new FooAbstract(); 16 | Serial.println( 17 | a1.FooFunction1(1) + 18 | a1.FooFunction2(2) + 19 | a1.FooFunction3(3) + 20 | a1[5.triple()]); 21 | } 22 | /* end using abstract type */ 23 | 24 | /* casting & override */ 25 | { 26 | var n1 = new ChildNo1(); 27 | var n2 = new ChildNo2(); 28 | var b0 = new Base(); 29 | var castedN1 = cast(n1, Base); 30 | var castedN2 = cast(n2, Base); 31 | var result1 = castedN1.getName() == n1.getName(); // asset TRUE 32 | var result2 = castedN2.getName() == n2.getName(); // asset TRUE 33 | var result3 = b0.getName() == n2.getName(); // asset FALSE 34 | } 35 | /* end casting & override */ 36 | 37 | /* property test */ 38 | { 39 | var d1 = new BarClass(); 40 | 41 | Serial.println(d1.x1); 42 | } 43 | /* end property test */ 44 | 45 | /* Literals test */ 46 | { 47 | Serial.println(Literals.n1); 48 | Serial.println(Literals.n2); 49 | Serial.println(Literals.n3); 50 | //Serial.println(Std.string(Literals.n4)); 51 | Serial.println(Std.string(Literals.n5)); 52 | Serial.println(Std.string(Literals.n6)); 53 | } 54 | /* end Literals test */ 55 | 56 | SampleFromSite.StaticMethod(); 57 | } 58 | 59 | public function loop() { } 60 | static function main() { } 61 | } -------------------------------------------------------------------------------- /examples/06-advanced-type-objects/src/foo/BarClass.hx: -------------------------------------------------------------------------------- 1 | package foo; 2 | 3 | class BarClass extends BarClassBase { 4 | public function new() { } 5 | 6 | 7 | public var x1(default, null):Int; 8 | public var x2(get, never):String; 9 | } 10 | 11 | class BarClassBase { 12 | public function get_x2(): String 13 | return "test_getter"; 14 | } -------------------------------------------------------------------------------- /examples/06-advanced-type-objects/src/foo/Extender.hx: -------------------------------------------------------------------------------- 1 | package foo; 2 | 3 | class IntExtender { 4 | static public function triple(i:Int) { 5 | return i * 3; 6 | } 7 | } -------------------------------------------------------------------------------- /examples/06-advanced-type-objects/src/foo/FooAbstract.hx: -------------------------------------------------------------------------------- 1 | package foo; 2 | 3 | 4 | abstract FooAbstract(Int) from Int to Int { 5 | 6 | public function new() 7 | this = 0; 8 | 9 | public static function FooStaticFunction(): FooAbstract 10 | return 1 + 1; 11 | public function FooFunction1(i: Int): FooAbstract 12 | return i++; 13 | public function FooFunction2(i: Int): FooAbstract 14 | return i + IncrementThis1(); 15 | public function FooFunction3(f: FooAbstract): Int 16 | return f.IncrementThis2(); 17 | 18 | public function IncrementThis1(): FooAbstract 19 | return this + 1; 20 | public inline function IncrementThis2(): FooAbstract 21 | return this++ + ++this; 22 | 23 | @:op(A + B) 24 | public function op_add(b: Int): FooAbstract 25 | return this + b; 26 | 27 | 28 | @:arrayAccess 29 | public inline function incrementWithIndexer(value:Int): FooAbstract { 30 | return this + value; 31 | } 32 | } -------------------------------------------------------------------------------- /examples/06-advanced-type-objects/src/foo/Literals.hx: -------------------------------------------------------------------------------- 1 | package foo; 2 | 3 | class Literals { 4 | public static var n1: Int = 0xFF42 + 232; 5 | public static var n2: Float = 0.32 - 3. + 2.1e5; 6 | public static var n3: Int = "\n".code; 7 | // TODO need implementation for support anon types 8 | //public static var n4 = { foo: 1, bar: 2 }; 9 | public static var n5 = 1...3; 10 | public static var n6 = ["a" => 1]; 11 | } -------------------------------------------------------------------------------- /examples/06-advanced-type-objects/src/foo/SampleFromSite.hx: -------------------------------------------------------------------------------- 1 | package foo; 2 | 3 | class SampleFromSite { 4 | public static function StaticMethod() { 5 | var playerA = { name: "Simon", move: Paper } 6 | var playerB = { name: "Nicolas", move: Rock } 7 | 8 | var result = switch [playerA.move, playerB.move] { 9 | case [Rock, Scissors] | 10 | [Paper, Rock] | 11 | [Scissors, Paper]: Winner(playerA); 12 | 13 | case [Rock, Paper] | 14 | [Paper, Scissors] | 15 | [Scissors, Rock]: Winner(playerB); 16 | 17 | case _: Draw; 18 | } 19 | trace('result: $result'); 20 | } 21 | } 22 | 23 | typedef Player = { name: String, move: Move } 24 | 25 | enum Move { Rock; Paper; Scissors; } 26 | 27 | enum Result { 28 | Winner(player:Player); 29 | Draw; 30 | } -------------------------------------------------------------------------------- /examples/06-advanced-type-objects/src/foo/Varianse.hx: -------------------------------------------------------------------------------- 1 | package foo; 2 | 3 | class Base { 4 | public function new() {} 5 | 6 | public function getName(): String 7 | return "BaseClass"; 8 | } 9 | class ChildNo1 extends Base { 10 | public function new() { 11 | super(); 12 | } 13 | 14 | public override function getName():String 15 | return "ChildNo1Class"; 16 | } 17 | class ChildNo2 extends Base { 18 | public function new() { 19 | super(); 20 | } 21 | 22 | public override function getName():String 23 | return "ChildNo2Class"; 24 | } -------------------------------------------------------------------------------- /extraParams.hxml: -------------------------------------------------------------------------------- 1 | # call the given macro before typing anything else 2 | --macro ast2obj.Generator.generate() 3 | # compiles but does not generate any file 4 | --no-output 5 | -------------------------------------------------------------------------------- /haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.2.2", 3 | "contributors": [ 4 | "ianharrigan" 5 | ], 6 | "dependencies": {}, 7 | "releasenote": "clean", 8 | "tags": [ 9 | "arduino" 10 | ], 11 | "license": "MIT", 12 | "name": "hxArduino", 13 | "description": "custom haxe generator to create arduino specific c++", 14 | "classPath": "src", 15 | "url": "https://github.com/ianharrigan/hxArduino" 16 | } -------------------------------------------------------------------------------- /lib/AutoPtr.h: -------------------------------------------------------------------------------- 1 | #ifndef AutoPtr_h_ 2 | #define AutoPtr_h_ 1 3 | 4 | /** 5 | * @brief AutoPtr is a "smart" pointer for classes implementing reference counting based garbage collection. 6 | * 7 | * To be usable with the AutoPtr template, a class must 8 | * implement the following behaviour: 9 | * 10 | * - A class must maintain a reference count. 11 | * - The constructors of the object initialize the reference count to one. 12 | * - The class must implement a public duplicate() method: 13 | * void duplicate(); 14 | * that increments the reference count by one. 15 | * - The class must implement a public release() method: 16 | * void release() 17 | * that decrements the reference count by one, and, 18 | * if the reference count reaches zero, deletes the 19 | * object. 20 | * 21 | * AutoPtr works in the following way: 22 | * - If an AutoPtr is assigned an ordinary pointer to 23 | * an object (via the constructor or the assignment operator), 24 | * it takes ownership of the object and the object's reference 25 | * count remains unchanged. 26 | * - If the AutoPtr is assigned another AutoPtr, the 27 | * object's reference count is incremented by one by 28 | * calling duplicate() on its object. 29 | * - The destructor of AutoPtr calls release() on its 30 | * object. 31 | * - AutoPtr supports dereferencing with both the -> 32 | * and the * operator. An attempt to dereference a null 33 | * AutoPtr results in a error that will cause application termination. 34 | * AutoPtr also implements all relational operators. 35 | * Note that AutoPtr allows casting of its encapsulated data types. 36 | */ 37 | #define NULL 0 38 | 39 | template 40 | class AutoPtr 41 | { 42 | public: 43 | /// Default constructor. Creates a new instance that points to nothing 44 | AutoPtr() : _ptr( NULL ) {} 45 | 46 | /// Create an auto pointer that takes ownership of the specified pointer 47 | AutoPtr( C* ptr ) : _ptr( ptr ) {} 48 | 49 | /** 50 | * @brief AutoPtr Create an auto pointer that takes ownership of the specified pointer 51 | * @param ptr The pointer to take ownership of 52 | * @param shared If \c true then increment the reference count for the 53 | * specified pointer. 54 | */ 55 | AutoPtr( C* ptr, bool shared ) : _ptr( ptr ) 56 | { 57 | if ( shared && _ptr ) _ptr->duplicate(); 58 | } 59 | 60 | /// Copy constructor. Increases the reference count for the owned object. 61 | AutoPtr( const AutoPtr& ptr ) : _ptr( ptr._ptr ) 62 | { 63 | if ( _ptr ) _ptr->duplicate(); 64 | } 65 | 66 | /// Copy constructor for taking ownership of another type of object 67 | template 68 | AutoPtr( const AutoPtr& ptr ) : _ptr( const_cast( ptr.get() ) ) 69 | { 70 | if ( _ptr ) _ptr->duplicate(); 71 | } 72 | 73 | /// Destructor. Invokes \c release on the owned object. 74 | ~AutoPtr() { if ( _ptr ) _ptr->release(); } 75 | 76 | /// Use to (re)set the owned object. If current owned object is not 77 | /// \c null, invokes \c release on the object. 78 | AutoPtr& assign( C* ptr ) 79 | { 80 | if ( _ptr != ptr ) 81 | { 82 | if ( _ptr ) _ptr->release(); 83 | _ptr = ptr; 84 | } 85 | 86 | return *this; 87 | } 88 | 89 | /** 90 | * @brief Reset the owned object. If current owned object is not 91 | * \c null, invokes \c release on the object. Will invoke \c duplicate 92 | * on the new instance if \c shared is specified 93 | * @param ptr The new object to take ownership of. 94 | * @param shared If \c true, \c duplicate() the owned object. 95 | * @return Reference to this instance for convenience. 96 | */ 97 | AutoPtr& assign( C* ptr, bool shared ) 98 | { 99 | if ( _ptr != ptr ) 100 | { 101 | if ( _ptr ) _ptr->release(); 102 | _ptr = ptr; 103 | if (shared && _ptr) _ptr->duplicate(); 104 | } 105 | return *this; 106 | } 107 | 108 | /// Share the pointer owned by the specified auto pointer instance. 109 | AutoPtr& assign( const AutoPtr& ptr ) 110 | { 111 | if ( &ptr != this ) 112 | { 113 | if ( _ptr ) _ptr->release(); 114 | _ptr = ptr._ptr; 115 | if ( _ptr ) _ptr->duplicate(); 116 | } 117 | 118 | return *this; 119 | } 120 | 121 | /// Share the pointer owned by the specified auto pointer of different type. 122 | template 123 | AutoPtr& assign( const AutoPtr& ptr ) 124 | { 125 | if ( ptr.get() != _ptr ) 126 | { 127 | if ( _ptr ) _ptr->release(); 128 | _ptr = const_cast( ptr.get() ); 129 | if ( _ptr ) _ptr->duplicate(); 130 | } 131 | 132 | return *this; 133 | } 134 | 135 | /// Copy assignment operator. Delegates to {@link #assign}. 136 | AutoPtr& operator = ( C* ptr ) 137 | { 138 | return assign( ptr ); 139 | } 140 | 141 | /// Copy assignment operator. Delegates to {@link #assign}. 142 | AutoPtr& operator = ( const AutoPtr& ptr ) 143 | { 144 | return assign( ptr ); 145 | } 146 | 147 | /// Copy assignment operator. Delegates to {@link #assign}. 148 | template 149 | AutoPtr& operator = ( const AutoPtr& ptr ) 150 | { 151 | return assign(ptr); 152 | } 153 | 154 | /// Swap the pointers of this instance with the specified instance. 155 | void swap( AutoPtr& ptr ) 156 | { 157 | swap( _ptr, ptr._ptr ); 158 | } 159 | 160 | /// Casts the AutoPtr via a dynamic cast to the given type. 161 | /// Returns an AutoPtr containing NULL if the cast fails. 162 | /// Example: (assume class Sub: public Super) 163 | /// AutoPtr super(new Sub()); 164 | /// AutoPtr sub = super.cast(); 165 | /// poco_assert (sub.get()); 166 | template 167 | AutoPtr cast() const 168 | { 169 | Other* pOther = dynamic_cast( _ptr ); 170 | return AutoPtr( pOther, true ); 171 | } 172 | 173 | /// Casts the AutoPtr via a static cast to the given type. 174 | /// Example: (assume class Sub: public Super) 175 | /// AutoPtr super(new Sub()); 176 | /// AutoPtr sub = super.unsafeCast(); 177 | /// poco_assert (sub.get()); 178 | template 179 | AutoPtr unsafeCast() const 180 | { 181 | Other* pOther = static_cast(_ptr); 182 | return AutoPtr(pOther, true); 183 | } 184 | 185 | /// Pointer acess operator for the owned object. Returns \c NULL if invalid 186 | C* operator -> () { return _ptr; } 187 | 188 | /// Pointer acess operator for the owned object. Returns \c NULL if invalid 189 | const C* operator -> () const { return _ptr; } 190 | 191 | /// Dereference operator for the owned object. Will lead to program 192 | /// termination if the owned object is not valid 193 | C& operator * () { return *_ptr; } 194 | 195 | /// Dereference operator for the owned object. Will lead to program 196 | /// termination if the owned object is not valid 197 | const C& operator * () const { return *_ptr; } 198 | 199 | /// Return the owned pointer. Callers must not \c delete 200 | C* get() { return _ptr; } 201 | 202 | /// Return the owned pointer. Callers must not \c delete 203 | const C* get() const { return _ptr; } 204 | 205 | /// Function operator. Return the owned pointer 206 | operator C* () { return _ptr; } 207 | 208 | /// Function operator. Return the owned pointer 209 | operator const C* () const { return _ptr; } 210 | 211 | /// Negative check of make sure the owned pointer is not valid. 212 | bool operator ! () const { return _ptr == 0; } 213 | 214 | /// Negative check of make sure the owned pointer is not valid. 215 | bool isNull() const { return _ptr == 0; } 216 | 217 | /// Invokes \c duplicate() on the owned pointer if valid. 218 | C* duplicate() 219 | { 220 | if ( _ptr ) _ptr->duplicate(); 221 | return _ptr; 222 | } 223 | 224 | /// Compare the owned objects for equality 225 | bool operator == ( const AutoPtr& ptr ) const 226 | { 227 | return _ptr == ptr._ptr; 228 | } 229 | 230 | /// Compare the owned object against the specified object for equality 231 | bool operator == ( const C* ptr ) const { return _ptr == ptr; } 232 | 233 | /// Compare the owned object against the specified object for equality 234 | bool operator == (C* ptr) const { return _ptr == ptr; } 235 | 236 | /// Compare the owned objects for inequality 237 | bool operator != (const AutoPtr& ptr) const 238 | { 239 | return _ptr != ptr._ptr; 240 | } 241 | 242 | /// Compare the owned object against the specified object for inequality 243 | bool operator != ( const C* ptr ) const { return _ptr != ptr; } 244 | 245 | /// Compare the owned object against the specified object for inequality 246 | bool operator != ( C* ptr ) const { return _ptr != ptr; } 247 | 248 | /// Compare the owned objects for ordering 249 | bool operator < ( const AutoPtr& ptr ) const 250 | { 251 | return _ptr < ptr._ptr; 252 | } 253 | 254 | /// Compare the owned object against the specified object for ordering 255 | bool operator < ( const C* ptr ) const { return _ptr < ptr; } 256 | 257 | /// Compare the owned object against the specified object for ordering 258 | bool operator < ( C* ptr ) const { return _ptr < ptr; } 259 | 260 | bool operator <= ( const AutoPtr& ptr ) const 261 | { 262 | return _ptr <= ptr._ptr; 263 | } 264 | 265 | bool operator <= ( const C* ptr ) const { return _ptr <= ptr; } 266 | 267 | bool operator <= ( C* ptr ) const { return _ptr <= ptr; } 268 | 269 | bool operator > ( const AutoPtr& ptr ) const 270 | { 271 | return _ptr > ptr._ptr; 272 | } 273 | 274 | bool operator > ( const C* ptr ) const { return _ptr > ptr; } 275 | 276 | bool operator > ( C* ptr ) const { return _ptr > ptr; } 277 | 278 | bool operator >= ( const AutoPtr& ptr ) const 279 | { 280 | return _ptr >= ptr._ptr; 281 | } 282 | 283 | bool operator >= ( const C* ptr ) const { return _ptr >= ptr; } 284 | 285 | bool operator >= ( C* ptr ) const { return _ptr >= ptr; } 286 | 287 | private: 288 | C* _ptr; 289 | }; 290 | 291 | 292 | template 293 | inline void swap( AutoPtr& p1, AutoPtr& p2 ) 294 | { 295 | p1.swap( p2 ); 296 | } 297 | 298 | #endif -------------------------------------------------------------------------------- /lib/HxObject.h: -------------------------------------------------------------------------------- 1 | #ifndef hxObject_h_ 2 | #define hxObject_h_ 1 3 | 4 | #include "RefCountedObject.h" 5 | 6 | class HxObject : public RefCountedObject { 7 | public: 8 | 9 | template 10 | bool isA() { 11 | return (dynamic_cast(this) != nullptr); 12 | } 13 | }; 14 | 15 | #endif -------------------------------------------------------------------------------- /lib/LinkedList.h: -------------------------------------------------------------------------------- 1 | /* 2 | LinkedList.h - V1.1 - Generic LinkedList implementation 3 | Works better with FIFO, because LIFO will need to 4 | search the entire List to find the last one; 5 | 6 | For instructions, go to https://github.com/ivanseidel/LinkedList 7 | 8 | Created by Ivan Seidel Gomes, March, 2013. 9 | Released into the public domain. 10 | */ 11 | 12 | 13 | #ifndef LinkedList_h 14 | #define LinkedList_h 15 | 16 | #include 17 | 18 | template 19 | struct ListNode 20 | { 21 | T data; 22 | ListNode *next; 23 | }; 24 | 25 | template 26 | class LinkedList { 27 | 28 | protected: 29 | int _size; 30 | ListNode *root; 31 | ListNode *last; 32 | 33 | // Helps "get" method, by saving last position 34 | ListNode *lastNodeGot; 35 | int lastIndexGot; 36 | // isCached should be set to FALSE 37 | // everytime the list suffer changes 38 | bool isCached; 39 | 40 | ListNode* getNode(int index); 41 | 42 | ListNode* findEndOfSortedString(ListNode *p, int(*cmp)(T &, T &)); 43 | 44 | public: 45 | // Copy constructor 46 | LinkedList(const LinkedList ©) { 47 | LinkedList &a = const_cast&>(copy); 48 | for (int i = 0; i < a.size(); i++) { 49 | add(a.get(i)); 50 | } 51 | } 52 | 53 | void operator = (const LinkedList &rhs) { 54 | LinkedList &a = const_cast&>(rhs); 55 | for (int i = 0; i < a.size(); i++) { 56 | add(a.get(i)); 57 | } 58 | } 59 | 60 | LinkedList(); 61 | ~LinkedList(); 62 | 63 | /* 64 | Returns current size of LinkedList 65 | */ 66 | virtual int size(); 67 | /* 68 | Adds a T object in the specified index; 69 | Unlink and link the LinkedList correcly; 70 | Increment _size 71 | */ 72 | virtual bool add(int index, T); 73 | /* 74 | Adds a T object in the end of the LinkedList; 75 | Increment _size; 76 | */ 77 | virtual bool add(T); 78 | /* 79 | Adds a T object in the start of the LinkedList; 80 | Increment _size; 81 | */ 82 | virtual bool unshift(T); 83 | /* 84 | Set the object at index, with T; 85 | Increment _size; 86 | */ 87 | virtual bool set(int index, T); 88 | /* 89 | Remove object at index; 90 | If index is not reachable, returns false; 91 | else, decrement _size 92 | */ 93 | virtual T remove(int index); 94 | /* 95 | Remove last object; 96 | */ 97 | virtual T pop(); 98 | /* 99 | Remove first object; 100 | */ 101 | virtual T shift(); 102 | /* 103 | Get the index'th element on the list; 104 | Return Element if accessible, 105 | else, return false; 106 | */ 107 | virtual T get(int index); 108 | 109 | /* 110 | Clear the entire array 111 | */ 112 | virtual void clear(); 113 | 114 | /* 115 | Sort the list, given a comparison function 116 | */ 117 | virtual void sort(int(*cmp)(T &, T &)); 118 | 119 | // added concat function (likely ineffecient - esp for large arrays - which probably wouldnt make sense on arduino anyway) 120 | LinkedList concat(LinkedList &a) { 121 | LinkedList out; 122 | for (int i = 0; i < size(); i++) { 123 | out.add(get(i)); 124 | } 125 | for (int i = 0; i < a.size(); i++) { 126 | out.add(a.get(i)); 127 | } 128 | 129 | return out; 130 | } 131 | 132 | }; 133 | 134 | // Initialize LinkedList with false values 135 | template 136 | LinkedList::LinkedList() 137 | { 138 | root = NULL; 139 | last = NULL; 140 | _size = 0; 141 | 142 | lastNodeGot = root; 143 | lastIndexGot = 0; 144 | isCached = false; 145 | } 146 | 147 | // Clear Nodes and free Memory 148 | template 149 | LinkedList::~LinkedList() 150 | { 151 | ListNode* tmp; 152 | while (root != NULL) 153 | { 154 | tmp = root; 155 | root = root->next; 156 | delete tmp; 157 | } 158 | last = NULL; 159 | _size = 0; 160 | isCached = false; 161 | } 162 | 163 | /* 164 | Actualy "logic" coding 165 | */ 166 | 167 | template 168 | ListNode* LinkedList::getNode(int index) { 169 | 170 | int _pos = 0; 171 | ListNode* current = root; 172 | 173 | // Check if the node trying to get is 174 | // immediatly AFTER the previous got one 175 | if (isCached && lastIndexGot <= index) { 176 | _pos = lastIndexGot; 177 | current = lastNodeGot; 178 | } 179 | 180 | while (_pos < index && current) { 181 | current = current->next; 182 | 183 | _pos++; 184 | } 185 | 186 | // Check if the object index got is the same as the required 187 | if (_pos == index) { 188 | isCached = true; 189 | lastIndexGot = index; 190 | lastNodeGot = current; 191 | 192 | return current; 193 | } 194 | 195 | return NULL; 196 | } 197 | 198 | template 199 | int LinkedList::size() { 200 | return _size; 201 | } 202 | 203 | template 204 | bool LinkedList::add(int index, T _t) { 205 | 206 | if (index >= _size) 207 | return add(_t); 208 | 209 | if (index == 0) 210 | return unshift(_t); 211 | 212 | ListNode *tmp = new ListNode(), 213 | *_prev = getNode(index - 1); 214 | tmp->data = _t; 215 | tmp->next = _prev->next; 216 | _prev->next = tmp; 217 | 218 | _size++; 219 | isCached = false; 220 | 221 | return true; 222 | } 223 | 224 | template 225 | bool LinkedList::add(T _t) { 226 | 227 | ListNode *tmp = new ListNode(); 228 | tmp->data = _t; 229 | tmp->next = NULL; 230 | 231 | if (root) { 232 | // Already have elements inserted 233 | last->next = tmp; 234 | last = tmp; 235 | } 236 | else { 237 | // First element being inserted 238 | root = tmp; 239 | last = tmp; 240 | } 241 | 242 | _size++; 243 | isCached = false; 244 | 245 | return true; 246 | } 247 | 248 | template 249 | bool LinkedList::unshift(T _t) { 250 | 251 | if (_size == 0) 252 | return add(_t); 253 | 254 | ListNode *tmp = new ListNode(); 255 | tmp->next = root; 256 | tmp->data = _t; 257 | root = tmp; 258 | 259 | _size++; 260 | isCached = false; 261 | 262 | return true; 263 | } 264 | 265 | template 266 | bool LinkedList::set(int index, T _t) { 267 | // Check if index position is in bounds 268 | if (index < 0 || index >= _size) 269 | return false; 270 | 271 | getNode(index)->data = _t; 272 | return true; 273 | } 274 | 275 | template 276 | T LinkedList::pop() { 277 | if (_size <= 0) 278 | return T(); 279 | 280 | isCached = false; 281 | 282 | if (_size >= 2) { 283 | ListNode *tmp = getNode(_size - 2); 284 | T ret = tmp->next->data; 285 | delete(tmp->next); 286 | tmp->next = NULL; 287 | last = tmp; 288 | _size--; 289 | return ret; 290 | } 291 | else { 292 | // Only one element left on the list 293 | T ret = root->data; 294 | delete(root); 295 | root = NULL; 296 | last = NULL; 297 | _size = 0; 298 | return ret; 299 | } 300 | } 301 | 302 | template 303 | T LinkedList::shift() { 304 | if (_size <= 0) 305 | return T(); 306 | 307 | if (_size > 1) { 308 | ListNode *_next = root->next; 309 | T ret = root->data; 310 | delete(root); 311 | root = _next; 312 | _size--; 313 | isCached = false; 314 | 315 | return ret; 316 | } 317 | else { 318 | // Only one left, then pop() 319 | return pop(); 320 | } 321 | 322 | } 323 | 324 | template 325 | T LinkedList::remove(int index) { 326 | if (index < 0 || index >= _size) 327 | { 328 | return T(); 329 | } 330 | 331 | if (index == 0) 332 | return shift(); 333 | 334 | if (index == _size - 1) 335 | { 336 | return pop(); 337 | } 338 | 339 | ListNode *tmp = getNode(index - 1); 340 | ListNode *toDelete = tmp->next; 341 | T ret = toDelete->data; 342 | tmp->next = tmp->next->next; 343 | delete(toDelete); 344 | _size--; 345 | isCached = false; 346 | return ret; 347 | } 348 | 349 | 350 | template 351 | T LinkedList::get(int index) { 352 | ListNode *tmp = getNode(index); 353 | 354 | return (tmp ? tmp->data : T()); 355 | } 356 | 357 | template 358 | void LinkedList::clear() { 359 | while (size() > 0) 360 | shift(); 361 | } 362 | 363 | template 364 | void LinkedList::sort(int(*cmp)(T &, T &)) { 365 | if (_size < 2) return; // trivial case; 366 | 367 | for (;;) { 368 | 369 | ListNode **joinPoint = &root; 370 | 371 | while (*joinPoint) { 372 | ListNode *a = *joinPoint; 373 | ListNode *a_end = findEndOfSortedString(a, cmp); 374 | 375 | if (!a_end->next) { 376 | if (joinPoint == &root) { 377 | last = a_end; 378 | isCached = false; 379 | return; 380 | } 381 | else { 382 | break; 383 | } 384 | } 385 | 386 | ListNode *b = a_end->next; 387 | ListNode *b_end = findEndOfSortedString(b, cmp); 388 | 389 | ListNode *tail = b_end->next; 390 | 391 | a_end->next = NULL; 392 | b_end->next = NULL; 393 | 394 | while (a && b) { 395 | if (cmp(a->data, b->data) <= 0) { 396 | *joinPoint = a; 397 | joinPoint = &a->next; 398 | a = a->next; 399 | } 400 | else { 401 | *joinPoint = b; 402 | joinPoint = &b->next; 403 | b = b->next; 404 | } 405 | } 406 | 407 | if (a) { 408 | *joinPoint = a; 409 | while (a->next) a = a->next; 410 | a->next = tail; 411 | joinPoint = &a->next; 412 | } 413 | else { 414 | *joinPoint = b; 415 | while (b->next) b = b->next; 416 | b->next = tail; 417 | joinPoint = &b->next; 418 | } 419 | } 420 | } 421 | } 422 | 423 | template 424 | ListNode* LinkedList::findEndOfSortedString(ListNode *p, int(*cmp)(T &, T &)) { 425 | while (p->next && cmp(p->data, p->next->data) <= 0) { 426 | p = p->next; 427 | } 428 | 429 | return p; 430 | } 431 | 432 | #endif 433 | -------------------------------------------------------------------------------- /lib/MemoryFree.cpp: -------------------------------------------------------------------------------- 1 | #if (ARDUINO >= 100) 2 | #include 3 | #else 4 | #include 5 | #endif 6 | 7 | extern unsigned int __heap_start; 8 | extern void *__brkval; 9 | 10 | /* 11 | * The free list structure as maintained by the 12 | * avr-libc memory allocation routines. 13 | */ 14 | struct __freelist 15 | { 16 | size_t sz; 17 | struct __freelist *nx; 18 | }; 19 | 20 | /* The head of the free list structure */ 21 | extern struct __freelist *__flp; 22 | 23 | #include "MemoryFree.h" 24 | 25 | /* Calculates the size of the free list */ 26 | int freeListSize() 27 | { 28 | struct __freelist* current; 29 | int total = 0; 30 | for (current = __flp; current; current = current->nx) 31 | { 32 | total += 2; /* Add two bytes for the memory block's header */ 33 | total += (int) current->sz; 34 | } 35 | 36 | return total; 37 | } 38 | 39 | int freeMemory() 40 | { 41 | int free_memory; 42 | if ((int)__brkval == 0) 43 | { 44 | free_memory = ((int)&free_memory) - ((int)&__heap_start); 45 | } 46 | else 47 | { 48 | free_memory = ((int)&free_memory) - ((int)__brkval); 49 | free_memory += freeListSize(); 50 | } 51 | return free_memory; 52 | } 53 | 54 | int freeMemoryPercent() { 55 | return 100 / (static_cast(2048) / freeMemory()); 56 | } -------------------------------------------------------------------------------- /lib/MemoryFree.h: -------------------------------------------------------------------------------- 1 | // MemoryFree library based on code posted here: 2 | // http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1213583720/15 3 | // Extended by Matthew Murdoch to include walking of the free list. 4 | 5 | #ifndef MEMORY_FREE_H 6 | #define MEMORY_FREE_H 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | int freeMemory(); 13 | int freeMemoryPercent(); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /lib/RefCountedObject.h: -------------------------------------------------------------------------------- 1 | #ifndef RefCountedObject_h_ 2 | #define RefCountedObject_h_ 1 3 | 4 | /// A base class for objects that employ 5 | /// reference counting based garbage collection. 6 | /// 7 | /// Reference-counted objects inhibit construction 8 | /// by copying and assignment. 9 | class RefCountedObject 10 | { 11 | public: 12 | /// Creates the RefCountedObject. 13 | /// The initial reference count is one. 14 | RefCountedObject() : refcount( 1 ) {} 15 | 16 | /// Increments the object's reference count. 17 | void duplicate() const { ++refcount; } 18 | 19 | /// Decrements the object's reference count 20 | /// and deletes the object if the count 21 | /// reaches zero. 22 | void release() const; 23 | 24 | /// Returns the reference count. 25 | int referenceCount() const { return refcount; } 26 | 27 | protected: 28 | /// Destroys the RefCountedObject. 29 | virtual ~RefCountedObject() {} 30 | 31 | private: 32 | RefCountedObject( const RefCountedObject& ); 33 | RefCountedObject& operator = ( const RefCountedObject& ); 34 | 35 | mutable int refcount; 36 | }; 37 | 38 | 39 | inline void RefCountedObject::release() const 40 | { 41 | if ( --refcount == 0 ) delete this; 42 | } 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /lib/entry.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | main.cpp - Main loop for Arduino sketches 3 | Copyright (c) 2005-2013 Arduino Team. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | #include "Main.h" 22 | 23 | // Declared weak in Arduino.h to allow user redefinitions. 24 | int atexit(void (* /*func*/ )()) { return 0; } 25 | 26 | // Weak empty variant initialization function. 27 | // May be redefined by variant files. 28 | void initVariant() __attribute__((weak)); 29 | void initVariant() { } 30 | 31 | void setupUSB() __attribute__((weak)); 32 | void setupUSB() { } 33 | 34 | int main(void) 35 | { 36 | init(); 37 | 38 | initVariant(); 39 | 40 | #if defined(USBCON) 41 | USBDevice.attach(); 42 | #endif 43 | 44 | Main main; 45 | main.setup(); 46 | 47 | for (;;) { 48 | main.loop(); 49 | if (serialEventRun) serialEventRun(); 50 | } 51 | 52 | return 0; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /run.n: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ianharrigan/hxArduino/e831388db25159ae57b7773905f14c7d6886c5c4/run.n -------------------------------------------------------------------------------- /src/Arduino.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | /** 4 | @see https://www.arduino.cc/reference/en/ 5 | **/ 6 | @:include("Arduino.h") 7 | extern class Arduino { 8 | 9 | public static inline var LED_BUILTIN:Int = untyped 'LED_BUILTIN'; 10 | 11 | public static inline var A0:Int = untyped 'A0'; 12 | public static inline var A1:Int = untyped 'A1'; 13 | public static inline var A2:Int = untyped 'A2'; 14 | public static inline var A3:Int = untyped 'A3'; 15 | public static inline var A4:Int = untyped 'A4'; 16 | public static inline var A5:Int = untyped 'A5'; 17 | public static inline var A6:Int = untyped 'A6'; 18 | public static inline var A7:Int = untyped 'A7'; 19 | 20 | public static inline var INPUT:Int = untyped 'INPUT'; 21 | public static inline var OUTPUT:Int = untyped 'OUTPUT'; 22 | 23 | public static inline var HIGH:Int = untyped 'HIGH'; 24 | public static inline var LOW:Int = untyped 'LOW'; 25 | 26 | public static inline var CHANGE:Int = untyped 'CHANGE'; 27 | public static inline var RISING:Int = untyped 'RISING'; 28 | public static inline var FALLING:Int = untyped 'FALLING'; 29 | 30 | public static inline var MSBFIRST : Int = untyped 'MSBFIRST'; 31 | public static inline var LSBFIRST : Int = untyped 'LSBFIRST'; 32 | 33 | // --- Digital I/O 34 | 35 | /** 36 | Reads the value from a specified digital pin, either `HIGH` or `LOW` 37 | **/ 38 | static function digitalRead( pin : Int ) : Int; 39 | 40 | /** 41 | Write a `HIGH` or a `LOW` value to a digital pin. 42 | **/ 43 | static function digitalWrite( pin : Int, value : Int ) : Void; 44 | 45 | /** 46 | Configures the specified pin to behave either as an input or an output. 47 | **/ 48 | static function pinMode( pin : Int, mode : Int ) : Void; 49 | 50 | // --- Analog I/O 51 | 52 | /** 53 | Reads the value from the specified analog pin. 54 | **/ 55 | static function analogRead( pin : Int ) : Int; 56 | 57 | /** 58 | Configures the reference voltage used for analog input (i.e. the value used as the top of the input range) 59 | **/ 60 | static function analogReference( type : Int ) : Void; 61 | 62 | /** 63 | Writes an analog value (PWM wave) to a pin. 64 | **/ 65 | static function analogWrite( pin : Int, value : Int ) : Void; 66 | 67 | // --- Zero, Due & MKR Family 68 | //TODO 69 | 70 | // --- Advanced I/O 71 | 72 | /** 73 | Stops the generation of a square wave triggered by `tone()`. 74 | **/ 75 | static function noTone( pin : Int ) : Void; 76 | 77 | /** 78 | Reads a pulse (either `HIGH` or `LOW`) on a pin. 79 | **/ 80 | static function pulseIn( pin : Int, value : Int, timeout : Int ) : Float; 81 | 82 | /** 83 | Alternative to pulseIn() which is better at handling long pulse and interrupt affected scenarios. 84 | **/ 85 | static function pulseInLong( pin : Int, value : Int, ?timeout : Int ) : Float; 86 | 87 | /** 88 | Shifts in a byte of data one bit at a time. 89 | **/ 90 | static function shiftIn( dataPin : Int, clockPin : Int, bitOrder : Int ) : Int; 91 | 92 | /** 93 | Shifts out a byte of data one bit at a time. 94 | **/ 95 | static function shiftOut( dataPin : Int, clockPin : Int, bitOrder : Int, value : Int ) : Void; 96 | 97 | /** 98 | Shifts out a byte of data one bit at a time. 99 | **/ 100 | static function tone( pin : Int, frequency : Int, ?duration : Float ) : Void; 101 | 102 | // --- Time 103 | 104 | /** 105 | Pauses the program for the amount of time (in milliseconds). 106 | **/ 107 | static function delay( ms : Int ) : Void; 108 | 109 | /** 110 | Pauses the program for the amount of time (in microseconds). 111 | **/ 112 | static function delayMicroseconds( us : Int ) : Void; 113 | 114 | /** 115 | Returns the number of microseconds since the Arduino board began running the current program. 116 | **/ 117 | static function micros() : Float; 118 | 119 | /** 120 | Returns the number of milliseconds since the Arduino board began running the current program. 121 | **/ 122 | static function millis() : Float; 123 | 124 | // --- Math 125 | 126 | /** 127 | Calculates the absolute value of a number. 128 | **/ 129 | static function abs( x : Float ) : Float; 130 | 131 | /** 132 | Constrains a number to be within a range. 133 | **/ 134 | static function constrain( x : Float, a : Float, b : Float ) : Float; 135 | 136 | /** 137 | Re-maps a number from one range to another. 138 | **/ 139 | static function map( value:Int, fromLow:Int, fromHigh:Int, toLow:Int, toHigh:Int):Int; 140 | 141 | /** 142 | Calculates the maximum of two numbers. 143 | **/ 144 | static function max( x : Float, y : Float ) : Float; 145 | 146 | /** 147 | Calculates the minimum of two numbers. 148 | **/ 149 | static function min( x : Float, y : Float ) : Float; 150 | 151 | /** 152 | Calculates the value of a number raised to a power. 153 | **/ 154 | static function pow( base : Float, exponent : Float ) : Float; 155 | 156 | /** 157 | Calculates the square of a number: the number multiplied by itself. 158 | **/ 159 | static function sq( x : Float ) : Float; 160 | 161 | /** 162 | Calculates the square root of a number. 163 | **/ 164 | static function sqrt( x : Float ) : Float; 165 | 166 | // --- Trigonometry 167 | 168 | /** 169 | Calculates the cosine of an angle (in radians). 170 | **/ 171 | static function cos( rad : Float ) : Float; 172 | 173 | /** 174 | Calculates the sine of an angle (in radians). 175 | **/ 176 | static function sin( rad : Float ) : Float; 177 | 178 | /** 179 | Calculates the tangent of an angle (in radians). 180 | **/ 181 | static function tan( rad : Float ) : Float; 182 | 183 | // --- Characters 184 | 185 | /** 186 | Analyse if a char is alpha (that is a letter). 187 | Returns true if `thisChar` contains a letter. 188 | **/ 189 | static function isAlpha( thisChar : Int ) : Int; 190 | 191 | /** 192 | Analyse if a char is alphanumeric (that is a letter or a numbers). 193 | Returns true if `thisChar` contains either a number or a letter. 194 | **/ 195 | static function isAlphaNumeric( thisChar : Int ) : Int; 196 | 197 | /** 198 | Analyse if a char is Ascii. 199 | Returns true if `thisChar` contains an Ascii character. 200 | **/ 201 | static function isAscii( thisChar : Int ) : Int; 202 | 203 | /** 204 | Analyse if a char is a control character. 205 | Returns true if `thisChar` contains is a control character. 206 | **/ 207 | static function isControl( thisChar : Int ) : Int; 208 | 209 | /** 210 | Analyse if a char is a digit. 211 | Returns true if `thisChar` is a number. 212 | **/ 213 | static function isDigit( thisChar : Int ) : Int; 214 | 215 | /** 216 | Analyse if a char is printable with some content (space is printable but has no content). 217 | Returns true if `thisChar` is printable. 218 | **/ 219 | static function isGraph( thisChar : Int ) : Int; 220 | 221 | /** 222 | Analyse if a char is an hexadecimal digit (A-F, 0-9). 223 | Returns true if `thisChar` contains an hexadecimal digit. 224 | **/ 225 | static function isHexadecimalDigit( thisChar : Int ) : Int; 226 | 227 | /** 228 | Analyse if a char is lower case (that is a letter in lower case). 229 | Returns true if `thisChar` contains a letter in lower case. 230 | **/ 231 | static function isLowerCase( thisChar : Int ) : Int; 232 | 233 | /** 234 | Analyse if a char is printable (that is any character that produces an output, even a blank space). 235 | Returns true if `thisChar` is printable. 236 | **/ 237 | static function isPrintable( thisChar : Int ) : Int; 238 | 239 | /** 240 | Analyse if a char is punctuation (that is a comma, a semicolon, an exlamation mark and so on). 241 | Returns true if `thisChar` is punctuation. 242 | **/ 243 | static function isPunct( thisChar : Int ) : Int; 244 | 245 | /** 246 | Analyse if a char is the space character. 247 | Returns true if `thisChar` contains the space character. 248 | **/ 249 | static function isSpace( thisChar : Int ) : Int; 250 | 251 | /** 252 | Analyse if a char is upper case (that is, a letter in upper case). 253 | Returns true if `thisChar` is upper case. 254 | **/ 255 | static function isUpperCase( thisChar : Int ) : Int; 256 | 257 | /** 258 | Analyse if a char is a white space, that is space, formfeed ('\f'), newline ('\n'), carriage return ('\r'), horizontal tab ('\t'), and vertical tab ('\v')). 259 | Returns true if `thisChar` contains a white space. 260 | **/ 261 | static function isWhitespace( thisChar : Int ) : Int; 262 | 263 | // --- Random Numbers 264 | 265 | /** 266 | Generates pseudo-random numbers. 267 | **/ 268 | @:overload(function(min:Float,max:Float):Float{}) 269 | static function random( max : Float ) : Float; 270 | 271 | /** 272 | Initializes the pseudo-random number generator. 273 | **/ 274 | static function randomSeed( max : Float ) : Void; 275 | 276 | // --- Bits and Bytes 277 | 278 | /** 279 | Computes the value of the specified bit (bit 0 is 1, bit 1 is 2, bit 2 is 4, etc.). 280 | **/ 281 | static function bit( n : Int ) : Int; 282 | 283 | /** 284 | Clears (writes a 0 to) a bit of a numeric variable. 285 | **/ 286 | static function bitClear( x : Int, n : Int ) : Void; 287 | 288 | /** 289 | Reads a bit of a number. 290 | **/ 291 | static function bitRead( x : Int, n : Int ) : Int; 292 | 293 | /** 294 | Sets (writes a 1 to) a bit of a numeric variable. 295 | **/ 296 | static function bitSet( x : Int, n : Int ) : Void; 297 | 298 | /** 299 | Writes a bit of a numeric variable. 300 | **/ 301 | static function bitWrite( x : Int, n : Int ) : Void; 302 | 303 | /** 304 | Extracts the high-order (leftmost) byte of a word (or the second lowest byte of a larger data type). 305 | **/ 306 | static function highByte( x : Int ) : Int; 307 | 308 | /** 309 | Extracts the low-order (rightmost) byte of a variable (e.g. a word). 310 | **/ 311 | static function lowByte( x : Int ) : Int; 312 | 313 | // --- External Interrupts 314 | 315 | /** 316 | **/ 317 | static function attachInterrupt( pin : Int, ISR : Void->Void, mode : Int ) : Void; 318 | 319 | /** 320 | Turns off the given interrupt. 321 | **/ 322 | static function detachInterrupt( pin : Int ) : Void; 323 | 324 | // --- Interrupts 325 | 326 | /** 327 | Re-enables interrupts. 328 | **/ 329 | static function interrupts() : Void; 330 | 331 | /** 332 | Disables interrupts. 333 | **/ 334 | static function noInterrupts() : Void; 335 | 336 | } 337 | -------------------------------------------------------------------------------- /src/EEPROM.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | /** 4 | 5 | The microcontroller on the Arduino and Genuino AVR based board has EEPROM: memory whose values are kept when the board is turned off (like a tiny hard drive). 6 | This library enables you to read and write those bytes. 7 | 8 | @see https://www.arduino.cc/en/Reference/EEPROM 9 | **/ 10 | @:include("EEPROM.h") 11 | @:native("EEPROM") 12 | extern class EEPROM { 13 | 14 | /** 15 | Reads a byte from the EEPROM. 16 | **/ 17 | static function read( address : Int ) : Int; 18 | 19 | /** 20 | Write a byte to the EEPROM. 21 | **/ 22 | static function write( address : Int, value : Int ) : Void; 23 | 24 | /** 25 | Write a byte to the EEPROM. 26 | The value is written only if differs from the one already saved at the same address. 27 | **/ 28 | static function update( address : Int, value : Int ) : Void; 29 | 30 | /** 31 | Read any data type or object from the EEPROM. 32 | **/ 33 | static function get( address : Int, data : Float ) : Void; 34 | 35 | /** 36 | Write any data type or object to the EEPROM. 37 | **/ 38 | static function put( address : Int, data : Float ) : Void; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/Keyboard.hx: -------------------------------------------------------------------------------- 1 | 2 | import haxe.extern.EitherType; 3 | 4 | /** 5 | The keyboard functions enable 32u4 or SAMD micro based boards to send keystrokes to an attached computer through their micro’s native USB port. 6 | 7 | @see https://www.arduino.cc/reference/en/language/functions/usb/keyboard/ 8 | **/ 9 | @:include("Keyboard.h") 10 | @:native("Keyboard") 11 | extern class Keyboard { 12 | 13 | /** 14 | When used with a Leonardo or Due board, Keyboard.begin() starts emulating a keyboard connected to a computer. 15 | **/ 16 | static function begin() : Void; 17 | 18 | /** 19 | Stops the keyboard emulation to a connected computer. 20 | **/ 21 | static function end() : Void; 22 | 23 | /** 24 | When called, Keyboard.press() functions as if a key were pressed and held on your keyboard. 25 | **/ 26 | static function press( c : EitherType ) : Void; 27 | 28 | /** 29 | Sends a keystroke to a connected computer. 30 | **/ 31 | static function print( c : EitherType ) : Int; 32 | 33 | /** 34 | Sends a keystroke to a connected computer. 35 | **/ 36 | static function println( c : EitherType ) : Int; 37 | 38 | /** 39 | Lets go of the specified key. 40 | **/ 41 | static function release( c : EitherType ) : Int; 42 | 43 | /** 44 | Lets go of all keys currently pressed. 45 | **/ 46 | static function releaseAll() : Void; 47 | 48 | /** 49 | Sends a keystroke to a connected computer. 50 | **/ 51 | static function write( c : EitherType ) : Int; 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/LiquidCrystal.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | @:include("LiquidCrystal.h") 4 | @:stackOnly 5 | extern class LiquidCrystal { 6 | public function new(rs:Int, enable:Int, d0:Int, d1:Int, d2:Int, d3:Int) { 7 | } 8 | 9 | public function begin(cols:Int, rows:Int):Void; 10 | public function setCursor(col:Int, row:Int):Void; 11 | public function print(s:String):Void; 12 | public function clear():Void; 13 | } 14 | -------------------------------------------------------------------------------- /src/MemoryFree.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | @:include("MemoryFree.h") 4 | extern class MemoryFree { 5 | public static function freeMemory():Int; 6 | public static function freeMemoryPercent():Int; 7 | } -------------------------------------------------------------------------------- /src/Mouse.hx: -------------------------------------------------------------------------------- 1 | 2 | import haxe.extern.EitherType; 3 | 4 | /** 5 | The mouse functions enable 32u4 or SAMD micro based boards to control cursor movement on a connected computer through their micro’s native USB port. 6 | When updating the cursor position, it is always relative to the cursor’s previous location. 7 | 8 | @see https://www.arduino.cc/reference/en/language/functions/usb/mouse/ 9 | **/ 10 | @:include("Mouse.h") 11 | @:native("Mouse") 12 | extern class Mouse { 13 | 14 | public static inline var MOUSE_LEFT : Int = untyped 'MOUSE_LEFT'; 15 | public static inline var MOUSE_RIGHT : Int = untyped 'MOUSE_RIGHT'; 16 | public static inline var MOUSE_MIDDLE : Int = untyped 'MOUSE_MIDDLE'; 17 | 18 | /** 19 | Begins emulating the mouse connected to a computer. 20 | **/ 21 | static function begin() : Void; 22 | 23 | /** 24 | Sends a momentary click to the computer at the location of the cursor. 25 | **/ 26 | static function click( ?button : Int ) : Void; 27 | 28 | /** 29 | Stops emulating the mouse connected to a computer. 30 | **/ 31 | static function end() : Void; 32 | 33 | /** 34 | Moves the cursor on a connected computer. 35 | **/ 36 | static function move( xVal : Int, yPos : Int, wheel : Int ) : Void; 37 | 38 | /** 39 | Sends a button press to a connected computer. 40 | **/ 41 | static function press( ?button : Int ) : Void; 42 | 43 | /** 44 | Sends a message that a previously pressed button. 45 | **/ 46 | static function release( ?button : Int ) : Void; 47 | 48 | /** 49 | Checks the current status of all mouse buttons, and reports if any are pressed or not. 50 | **/ 51 | static function isPressed( ?button : Int ) : Int; 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/Serial.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | /** 4 | Used for communication between the Arduino board and a computer or other devices. 5 | 6 | @see https://www.arduino.cc/reference/en/language/functions/communication/serial/ 7 | **/ 8 | @:include("Arduino.h") 9 | @:native("Serial") 10 | extern class Serial { 11 | 12 | public static inline var SERIAL_5N1 : Int = untyped "SERIAL_5N1"; 13 | public static inline var SERIAL_6N1 : Int = untyped "SERIAL_6N1"; 14 | public static inline var SERIAL_7N1 : Int = untyped "SERIAL_7N1"; 15 | public static inline var SERIAL_8N1 : Int = untyped "SERIAL_8N1"; 16 | public static inline var SERIAL_5N2 : Int = untyped "SERIAL_5N2"; 17 | public static inline var SERIAL_6N2 : Int = untyped "SERIAL_6N2"; 18 | public static inline var SERIAL_7N2 : Int = untyped "SERIAL_7N2"; 19 | public static inline var SERIAL_8N2 : Int = untyped "SERIAL_8N2"; 20 | public static inline var SERIAL_5E1 : Int = untyped "SERIAL_5E1"; 21 | public static inline var SERIAL_6E1 : Int = untyped "SERIAL_6E1"; 22 | public static inline var SERIAL_7E1 : Int = untyped "SERIAL_7E1"; 23 | public static inline var SERIAL_8E1 : Int = untyped "SERIAL_8E1"; 24 | public static inline var SERIAL_5E2 : Int = untyped "SERIAL_5E2"; 25 | public static inline var SERIAL_6E2 : Int = untyped "SERIAL_6E2"; 26 | public static inline var SERIAL_7E2 : Int = untyped "SERIAL_7E2"; 27 | public static inline var SERIAL_8E2 : Int = untyped "SERIAL_8E2"; 28 | public static inline var SERIAL_5O1 : Int = untyped "SERIAL_5O1"; 29 | public static inline var SERIAL_6O1 : Int = untyped "SERIAL_6O1"; 30 | public static inline var SERIAL_7O1 : Int = untyped "SERIAL_7O1"; 31 | public static inline var SERIAL_8O1 : Int = untyped "SERIAL_8O1"; 32 | public static inline var SERIAL_5O2 : Int = untyped "SERIAL_5O2"; 33 | public static inline var SERIAL_6O2 : Int = untyped "SERIAL_6O2"; 34 | public static inline var SERIAL_7O2 : Int = untyped "SERIAL_7O2"; 35 | public static inline var SERIAL_8O2 : Int = untyped "SERIAL_8O2"; 36 | 37 | public static inline var BIN : Int = untyped "BIN"; 38 | public static inline var OCT : Int = untyped "OCT"; 39 | public static inline var DEC : Int = untyped "DEC"; 40 | public static inline var HEX : Int = untyped "HEX"; 41 | 42 | /** 43 | Get the number of bytes (characters) available for reading from the serial port. 44 | This is data that’s already arrived and stored in the serial receive buffer (which holds 64 bytes). available() inherits from the Stream utility class. 45 | **/ 46 | static function available() : Int; 47 | 48 | /** 49 | Get the number of bytes (characters) available for writing in the serial buffer without blocking the write operation. 50 | **/ 51 | static function availableForWrite() : Int; 52 | 53 | /** 54 | Sets the data rate in bits per second (baud) for serial data transmission. 55 | **/ 56 | static function begin( baud : Int, ?config : Int ) : Void; 57 | 58 | /** 59 | Disables serial communication, allowing the RX and TX pins to be used for general input and output. 60 | To re-enable serial communication, call `Serial.begin()`. 61 | **/ 62 | static function end() : Void; 63 | 64 | /** 65 | Serial.find() reads data from the serial buffer until the target string of given length is found. 66 | The function returns `true` if target string is found, `false` if it times out. 67 | **/ 68 | static function find( target : String ) : Int; 69 | 70 | /** 71 | Reads data from the serial buffer until a target string of given length or terminator string is found. 72 | The function returns `true` if the target string is found, `false` if it times out. 73 | **/ 74 | static function findUntil( target : Int, terminal : Int ) : Int; 75 | 76 | /** 77 | Waits for the transmission of outgoing serial data to complete. 78 | **/ 79 | static function flush() : Void; 80 | 81 | /** 82 | Returns the first valid floating point number from the Serial buffer. 83 | **/ 84 | static function parseFloat() : Float; 85 | 86 | /** 87 | Looks for the next valid integer in the incoming stream. 88 | **/ 89 | static function parseInt( ?skipChar : Int ) : Int; 90 | 91 | /** 92 | Returns the next byte (character) of incoming serial data without removing it from the internal serial buffer. 93 | **/ 94 | static function peek() : Int; 95 | 96 | /** 97 | Prints data to the serial port as human-readable ASCII text. 98 | **/ 99 | @:overload(function( val : String, ?format : Int) : Int {}) 100 | @:overload(function( val : Float, ?format : Int) : Int {}) 101 | static function print( val : Int, ?format : Int ) : Int; 102 | 103 | /** 104 | Prints data to the serial port as human-readable ASCII text followed by a carriage return character (ASCII 13, or '\r') and a newline character (ASCII 10, or '\n'). 105 | **/ 106 | @:overload(function( val : String, ?format : Int) : Int {}) 107 | @:overload(function( val : Float, ?format : Int) : Int {}) 108 | static function println( val : Int, ?format : Int ) : Int; 109 | 110 | /** 111 | Reads incoming serial data. 112 | Returns the first byte of incoming serial data available (or -1 if no data is available) 113 | **/ 114 | static function read() : Int; 115 | 116 | /** 117 | Reads characters from the serial port into a buffer. 118 | The function terminates if the determined length has been read, or it times out (see `Serial.setTimeout()`). 119 | **/ 120 | //TODO static function readBytes( buffer, length : Int ) : Int; 121 | 122 | /** 123 | **/ 124 | //TODO static function readBytesUntil() : Int; 125 | 126 | /** 127 | Reads characters from the serial buffer into a string. 128 | The function terminates if it times out (see `setTimeout()`). 129 | **/ 130 | static function readString() : String; 131 | 132 | /** 133 | Reads characters from the serial buffer into a string. 134 | The function terminates if it times out (see `setTimeout()`). 135 | **/ 136 | static function readStringUntil( terminator : Int ) : String; 137 | 138 | /** 139 | Sets the maximum milliseconds to wait for serial data when using serial.readBytesUntil() or serial.readBytes(). 140 | It defaults to 1000 milliseconds. 141 | **/ 142 | static function setTimeout( time : Float ) : Void; 143 | 144 | /** 145 | Writes binary data to the serial port. 146 | This data is sent as a byte or series of bytes; to send the characters representing the digits of a number use the `print()` function instead. 147 | **/ 148 | @:overload(function( val : Int, len : Int ) : Int {}) 149 | @:overload(function( val : String ) : Int {}) 150 | static function write( val : Int ) : Int; 151 | } 152 | -------------------------------------------------------------------------------- /src/Util.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | class Util { 4 | public static function addressOf(value:Float):Int { return 0; } 5 | } -------------------------------------------------------------------------------- /src/ast2obj/Generator.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | import ast2obj.builders.ArduinoCPPBuilder; 4 | import ast2obj.builders.Compiler; 5 | import haxe.macro.Expr.Binop; 6 | import haxe.macro.Expr.Unop; 7 | import haxe.macro.ExprTools; 8 | import haxe.macro.Context; 9 | import haxe.macro.Type; 10 | 11 | class Generator { 12 | #if macro 13 | public static function generate() { 14 | haxe.macro.Context.onGenerate(onGenerate); 15 | } 16 | #end 17 | 18 | public static function onGenerate(types:Array):Void { 19 | haxe.Log.trace = function(v:Dynamic, ?infos:haxe.PosInfos) { 20 | Sys.println(v); 21 | } 22 | 23 | var oclasses = []; 24 | 25 | for (t in types) { 26 | switch(t) { 27 | case TInst(c, params): 28 | var oclass = buildClass(c, params); 29 | if (oclass != null) { 30 | oclasses.push(oclass); 31 | } 32 | default: 33 | //trace(t); 34 | } 35 | } 36 | 37 | ArduinoCPPBuilder.basePath = Sys.getCwd(); 38 | ArduinoCPPBuilder.classes = oclasses; 39 | ArduinoCPPBuilder.build(); 40 | 41 | var libraries:Array = ArduinoCPPBuilder.libraries; 42 | Compiler.compile(ArduinoCPPBuilder.srcPath, ArduinoCPPBuilder.includePath, ArduinoCPPBuilder.outPath, libraries); 43 | } 44 | 45 | private static function buildClass(c:Ref, params:Array):OClass { 46 | if (c.toString() == "Array" || c.toString() == "Std" || c.toString() == "ArrayAccess" || c.toString() == "String" || c.toString() == "Type" 47 | || StringTools.startsWith(c.toString(), "haxe.") || c.toString() == "IntIterator" || c.toString() == "_EnumValue.EnumValue_Impl_" 48 | || c.toString() == "_Any.Any_Impl_" || c.toString() == "StringBuf") { 49 | trace("Skipping: " + c.toString()); 50 | return null; 51 | } else { 52 | trace("Generating: " + c.toString()); 53 | } 54 | 55 | var oclass = new OClass(); 56 | oclass.fullName = c.toString(); 57 | if (c.get().superClass != null) { 58 | oclass.superClass = new OClass(); 59 | oclass.superClass.fullName = c.get().superClass.t.toString(); 60 | } 61 | oclass.isExtern = c.get().isExtern; 62 | if (oclass.isExtern == true) { 63 | oclass.externIncludes = extractMetaValues(c.get().meta, ":include"); 64 | oclass.externName = extractMetaValue(c.get().meta, ":native"); 65 | } 66 | oclass.stackOnly = hasMeta(c.get().meta, ":stackOnly"); 67 | 68 | var classType:ClassType = c.get(); 69 | 70 | if (classType.constructor != null) { 71 | oclass.constructor = buildMethod(oclass, classType.constructor.get().expr()); 72 | if (oclass.constructor != null) { 73 | oclass.constructor.cls = oclass; 74 | } 75 | } 76 | 77 | var fields:Array = classType.fields.get(); 78 | for (f in fields) { 79 | switch (f.kind) { 80 | case FMethod(k): 81 | var omethod = buildMethod(oclass, f.expr()); 82 | if (omethod != null) { 83 | omethod.cls = oclass; 84 | omethod.name = f.name; 85 | oclass.methods.push(omethod); 86 | } 87 | case FVar(read, write): 88 | var oclassvar = buildClassVar(oclass, f.expr()); 89 | if (oclassvar != null) { 90 | oclassvar.type = buildType(f.type); 91 | oclassvar.cls = oclass; 92 | oclassvar.name = f.name; 93 | oclass.classVars.push(oclassvar); 94 | } 95 | case _: 96 | trace("buildClass not impl: " + f.kind); 97 | } 98 | } 99 | 100 | var fields:Array = classType.statics.get(); 101 | for (f in fields) { 102 | switch (f.kind) { 103 | case FMethod(k): 104 | var omethod = buildMethod(oclass, f.expr()); 105 | if (omethod != null) { 106 | omethod.cls = oclass; 107 | omethod.name = f.name; 108 | omethod.isStatic = true; 109 | oclass.methods.push(omethod); 110 | } 111 | case FVar(read, write): 112 | if (read == AccInline && write == AccNever) { 113 | // lets skip static inline constants, they will be replaced in the AST 114 | // with the actual value anyway 115 | continue; 116 | } 117 | var oclassvar = buildClassVar(oclass, f.expr()); 118 | if (oclassvar != null) { 119 | oclassvar.type = buildType(f.type); 120 | oclassvar.cls = oclass; 121 | oclassvar.name = f.name; 122 | oclassvar.isStatic = true; 123 | oclassvar.isConst = (read == AccInline && write == AccNever); 124 | oclass.classVars.push(oclassvar); 125 | } 126 | case _: 127 | trace("buildClass static not impl: " + f.kind); 128 | } 129 | } 130 | return oclass; 131 | } 132 | 133 | private static function buildClassVar(oclass:OClass, e:TypedExpr):OClassVar { 134 | var oclassvar = new OClassVar(); 135 | oclassvar.expression = buildExpression(e, null); 136 | return oclassvar; 137 | } 138 | 139 | private static function buildMethod(oclass:OClass, e:TypedExpr):OMethod { 140 | var omethod:OMethod = null; 141 | 142 | if (e != null) { 143 | switch (e.expr) { 144 | case TFunction(tfunc): 145 | omethod = new OMethod(); 146 | omethod.type = buildType(tfunc.t); 147 | for (arg in tfunc.args) { 148 | var omethodarg = new OMethodArg(); 149 | omethodarg.name = arg.v.name; 150 | omethodarg.type = buildType(arg.v.t); 151 | if (arg.value != null) { 152 | switch (arg.value.expr) { 153 | case TConst(c): 154 | omethodarg.value = buildConstant(c); 155 | default: 156 | trace("method arg type not impl: " + arg.value.expr); 157 | } 158 | } 159 | omethodarg.id = arg.v.id; 160 | omethod.args.push(omethodarg); 161 | } 162 | omethod.expression = buildExpression(tfunc.expr, null); 163 | case _: 164 | } 165 | } 166 | 167 | return omethod; 168 | } 169 | 170 | private static function buildExpression(e:TypedExpr, prevExpression:OExpression):OExpression { 171 | if (e == null) { 172 | return null; 173 | } 174 | 175 | var oexpr:OExpression = null; 176 | 177 | switch (e.expr) { 178 | case TBlock(el): 179 | oexpr = new OBlock(); 180 | for (e in el) { 181 | cast(oexpr, OBlock).expressions.push(buildExpression(e, oexpr)); 182 | } 183 | case TReturn(e): 184 | oexpr = new OReturn(); 185 | oexpr.nextExpression = buildExpression(e, oexpr); 186 | case TConst(c): 187 | oexpr = buildConstant(c); 188 | 189 | // so basically doing some really hacky crap here. If you have an untyped static int like: 190 | // public static inline var LED_BUILTIN:Int = untyped 'LED_BUILTIN'; 191 | // Then the type and the expr dont match (one is string, one is int), so we'll make the 192 | // awful assumption its supposed to be an int constant... will likely go completely wrong 193 | // somewhere 194 | if (cast(oexpr, OConstant).type != "this") { 195 | switch(e.t) { 196 | case TAbstract(t, params): 197 | if (cast(oexpr, OConstant).type != t.toString()) { 198 | var constantName:String = cast(oexpr, OConstant).value; 199 | oexpr = new OConstantIdentifier(); 200 | cast(oexpr, OConstantIdentifier).name = constantName; 201 | } 202 | case TInst(t, params): 203 | if (cast(oexpr, OConstant).type != t.toString()) { 204 | var constantName:String = cast(oexpr, OConstant).value; 205 | oexpr = new OConstantIdentifier(); 206 | cast(oexpr, OConstantIdentifier).name = constantName; 207 | } 208 | case _: 209 | } 210 | } 211 | 212 | case TVar(v, e): 213 | oexpr = new OVar(); 214 | cast(oexpr, OVar).name = v.name; 215 | cast(oexpr, OVar).type = buildType(v.t); 216 | oexpr.nextExpression = buildExpression(e, oexpr); 217 | case TBinop(op, e1, e2): 218 | oexpr = new OBinOp(); 219 | cast(oexpr, OBinOp).op = buildBinOp(op); 220 | cast(oexpr, OBinOp).expression = buildExpression(e1, oexpr); 221 | oexpr.nextExpression = buildExpression(e2, oexpr); 222 | case TLocal(v): 223 | oexpr = new OLocal(); 224 | oexpr.id = v.id; 225 | cast(oexpr, OLocal).name = v.name; 226 | cast(oexpr, OLocal).type = buildType(v.t); 227 | case TIf(econd, eif, eelse): 228 | oexpr = new OIf(); 229 | cast(oexpr, OIf).conditionExpression = buildExpression(econd, oexpr); 230 | if (isBlock(eif) == false) { 231 | var ifBlock:OBlock = new OBlock(); 232 | ifBlock.expressions.push(buildExpression(eif, oexpr)); 233 | cast(oexpr, OIf).ifExpression = ifBlock; 234 | } else { 235 | cast(oexpr, OIf).ifExpression = buildExpression(eif, oexpr); 236 | } 237 | if (eelse != null) { 238 | cast(oexpr, OIf).elseExpression = buildExpression(eelse, oexpr); 239 | } 240 | case TParenthesis(e): 241 | oexpr = new OParenthesis(); 242 | oexpr.nextExpression = buildExpression(e, oexpr); 243 | case TArrayDecl(el): 244 | oexpr = new OArrayDecl(); 245 | for (e in el) { 246 | cast(oexpr, OArrayDecl).expressions.push(buildExpression(e, oexpr)); 247 | } 248 | case TWhile(econd, e, true): 249 | oexpr = new OWhile(); 250 | cast(oexpr, OWhile).conditionExpression = buildExpression(econd, oexpr); 251 | oexpr.nextExpression = buildExpression(e, oexpr); 252 | case TField(e, FInstance(c, params, cf)): 253 | oexpr = new OFieldInstance(); 254 | cast(oexpr, OFieldInstance).cls = new OClass(); 255 | cast(oexpr, OFieldInstance).field = cf.get().name; 256 | cast(oexpr, OFieldInstance).cls.fullName += c.toString(); 257 | oexpr.nextExpression = buildExpression(e, oexpr); 258 | case TField(e, FStatic(c, cf)): 259 | oexpr = new OFieldStatic(); 260 | cast(oexpr, OFieldStatic).cls = new OClass(); 261 | cast(oexpr, OFieldStatic).cls.fullName += c.toString(); 262 | cast(oexpr, OFieldStatic).cls.isExtern = c.get().isExtern; 263 | if (cast(oexpr, OFieldStatic).cls.isExtern) { 264 | cast(oexpr, OFieldStatic).cls.externIncludes = extractMetaValues(c.get().meta, ":include"); 265 | cast(oexpr, OFieldStatic).cls.externName = extractMetaValue(c.get().meta, ":native"); 266 | } 267 | cast(oexpr, OFieldStatic).field = cf.get().name; 268 | oexpr.nextExpression = buildExpression(e, oexpr); 269 | case TArray(e1, e2): 270 | oexpr = new OArray(); 271 | cast(oexpr, OArray).varExpression = buildExpression(e1, oexpr); 272 | oexpr.nextExpression = buildExpression(e2, oexpr); 273 | case TUnop(op, postFix, e): 274 | oexpr = new OUnOp(); 275 | cast(oexpr, OUnOp).op = buildUnOp(op); 276 | cast(oexpr, OUnOp).post = postFix; 277 | oexpr.nextExpression = buildExpression(e, oexpr); 278 | case TNew(c, params, el): 279 | oexpr = new ONew(); 280 | cast(oexpr, ONew).cls = new OClass(); 281 | cast(oexpr, ONew).cls.fullName += c.toString(); 282 | for (e in el) { 283 | cast(oexpr, ONew).expressions.push(buildExpression(e, oexpr)); 284 | } 285 | case TCall(e, el): 286 | oexpr = new OCall(); 287 | oexpr.nextExpression = buildExpression(e, oexpr); 288 | for (e in el) { 289 | cast(oexpr, OCall).expressions.push(buildExpression(e, oexpr)); 290 | } 291 | case TTypeExpr(TClassDecl(c)): 292 | oexpr = new OTypeExprClass(); 293 | cast(oexpr, OTypeExprClass).cls = new OClass(); 294 | cast(oexpr, OTypeExprClass).cls.fullName += c.toString(); 295 | case TMeta(m, e): 296 | oexpr = buildExpression(e, prevExpression); 297 | case TSwitch(e, cases, edef): 298 | oexpr = new OSwitch(); 299 | cast(oexpr, OSwitch).type = buildType(e.t); 300 | cast(oexpr, OSwitch).expression = buildExpression(e, oexpr); 301 | for (c in cases) { 302 | var ocase = new OCase(); 303 | cast(oexpr, OSwitch).cases.push(ocase); 304 | for (t in c.values) { 305 | ocase.caseExpressions.push(buildExpression(t, oexpr)); 306 | if (isBlock(c.expr) == false) { 307 | var caseBlock:OBlock = new OBlock(); 308 | caseBlock.expressions.push(buildExpression(c.expr, oexpr)); 309 | ocase.expression = caseBlock; 310 | } else { 311 | ocase.expression = buildExpression(c.expr, oexpr); 312 | } 313 | buildExpression(t, oexpr); 314 | } 315 | } 316 | if (isBlock(edef) == false) { 317 | var caseBlock:OBlock = new OBlock(); 318 | caseBlock.expressions.push(buildExpression(edef, oexpr)); 319 | cast(oexpr, OSwitch).defaultExpression = caseBlock; 320 | } else { 321 | cast(oexpr, OSwitch).defaultExpression = buildExpression(edef, oexpr); 322 | } 323 | case _: 324 | trace("buildExpression not impl: " + e.expr); 325 | } 326 | 327 | if (oexpr != null) { 328 | oexpr.prevExpression = prevExpression; 329 | } 330 | 331 | return oexpr; 332 | } 333 | 334 | private static function isBlock(e:TypedExpr):Bool { 335 | switch (e.expr) { 336 | case TBlock(_): 337 | return true; 338 | case _: 339 | } 340 | return false; 341 | } 342 | 343 | private static function buildConstant(c:Null):OConstant { 344 | if (c == null) { 345 | return null; 346 | } 347 | 348 | var oconstant:OConstant = new OConstant(); 349 | 350 | switch (c) { 351 | case TInt(i): 352 | oconstant.type = "Int"; 353 | oconstant.value = i; 354 | case TString(s): 355 | oconstant.type = "String"; 356 | oconstant.value = s; 357 | case TBool(b): 358 | oconstant.type = "Bool"; 359 | oconstant.value = b; 360 | case TThis: 361 | oconstant.type = "this"; 362 | case TNull: 363 | oconstant.type = "null"; 364 | case _: 365 | trace("buildConstant not impl: " + c); 366 | } 367 | 368 | return oconstant; 369 | } 370 | 371 | private static function buildType(t:Type):OType { 372 | var otype = new OType(); 373 | 374 | switch (t) { 375 | case TAbstract(t, params): 376 | otype.name = t.toString(); 377 | case TInst(t, params): 378 | otype.name = t.toString(); 379 | for (p in params) { 380 | otype.typeParameters.push(buildType(p)); 381 | } 382 | case _: 383 | trace("buildType not impl: " + t); 384 | } 385 | 386 | return otype; 387 | } 388 | 389 | private static function extractMetaValue(meta:MetaAccess, name:String):String { 390 | var metaValue = null; 391 | 392 | if (meta.extract(name) != null && meta.extract(name).length > 0) { 393 | metaValue = ExprTools.toString(meta.extract(name)[0].params[0]); 394 | metaValue = StringTools.replace(metaValue, "\"", ""); 395 | } 396 | 397 | if (name == ":include" && metaValue != null) { 398 | metaValue = StringTools.replace(metaValue, ".h", ""); 399 | } 400 | 401 | return metaValue; 402 | } 403 | 404 | private static function extractMetaValues(meta:MetaAccess, name:String):Array { 405 | var metaValues = null; 406 | 407 | if (meta.extract(name) != null && meta.extract(name).length > 0) { 408 | metaValues = []; 409 | var metaEntries = meta.extract(name); 410 | for (m in metaEntries) { 411 | var metaValue:String = ExprTools.toString(m.params[0]); 412 | metaValue = StringTools.replace(metaValue, "\"", ""); 413 | metaValues.push(metaValue); 414 | } 415 | } 416 | 417 | return metaValues; 418 | } 419 | 420 | private static function hasMeta(meta:MetaAccess, name:String):Bool { 421 | var b = false; 422 | 423 | if (meta.extract(name) != null && meta.extract(name).length > 0) { 424 | b = true; 425 | } 426 | 427 | return b; 428 | } 429 | 430 | private static function buildBinOp(op:Binop) return switch(op) { 431 | case OpAdd: "+"; 432 | case OpMult: "*"; 433 | case OpDiv: "/"; 434 | case OpSub: "-"; 435 | case OpAssign: "="; 436 | case OpEq: "=="; 437 | case OpNotEq: "!="; 438 | case OpGt: ">"; 439 | case OpGte: ">="; 440 | case OpLt: "<"; 441 | case OpLte: "<="; 442 | case OpAnd: "&"; 443 | case OpOr: "|"; 444 | case OpXor: "^"; 445 | case OpBoolOr: "||"; 446 | case OpBoolAnd: "&&"; 447 | case OpShl: "<<"; 448 | case OpShr: ">>"; 449 | case OpUShr: ">>>"; 450 | case OpMod: "%"; 451 | case OpInterval: "..."; 452 | case OpArrow: "=>"; 453 | //case OpIn: " in "; 454 | case OpAssignOp(op): 455 | buildBinOp(op) 456 | + "="; 457 | case _: 458 | trace("buildBinOp not impl: " + op); 459 | return ""; 460 | } 461 | 462 | private static function buildUnOp(op:Unop) return switch(op) { 463 | case OpIncrement: "++"; 464 | case OpDecrement: "--"; 465 | case OpNot: "!"; 466 | case OpNeg: "-"; 467 | case OpNegBits: "~"; 468 | } 469 | } -------------------------------------------------------------------------------- /src/ast2obj/OArray.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OArray extends OExpression { 4 | public var varExpression:OExpression; 5 | } -------------------------------------------------------------------------------- /src/ast2obj/OArrayDecl.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OArrayDecl extends OExpression { 4 | public var expressions:Array = []; 5 | } -------------------------------------------------------------------------------- /src/ast2obj/OBinOp.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OBinOp extends OExpression { 4 | public var expression:OExpression; 5 | public var op:String = null; 6 | } -------------------------------------------------------------------------------- /src/ast2obj/OBlock.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OBlock extends OExpression { 4 | public var expressions:Array = []; 5 | } -------------------------------------------------------------------------------- /src/ast2obj/OCall.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OCall extends OExpression { 4 | public var expressions:Array = []; 5 | } -------------------------------------------------------------------------------- /src/ast2obj/OCase.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OCase extends OExpression { 4 | public var caseExpressions:Array = []; 5 | public var expression:OExpression; 6 | } -------------------------------------------------------------------------------- /src/ast2obj/OClass.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OClass { 4 | public var superClass:OClass; 5 | 6 | public var fullName:String = ""; 7 | public var isExtern:Bool = false; 8 | public var stackOnly:Bool = false; 9 | public var externName:String = null; 10 | public var externIncludes:Array = null; 11 | 12 | public var constructor:OMethod = null; 13 | public var methods:Array = []; 14 | public var classVars:Array = []; 15 | 16 | public function new() { 17 | } 18 | 19 | public var safeName(get, null):String; 20 | private function get_safeName():String { 21 | return StringTools.replace(fullName, ".", "_"); 22 | } 23 | } -------------------------------------------------------------------------------- /src/ast2obj/OClassVar.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OClassVar { 4 | public var cls:OClass; 5 | 6 | public var type:OType; 7 | public var name:String; 8 | public var isStatic:Bool = false; 9 | public var isConst:Bool = false; 10 | public var expression:OExpression; 11 | 12 | public function new() { 13 | } 14 | } -------------------------------------------------------------------------------- /src/ast2obj/OConstant.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OConstant extends OExpression { 4 | public var type:String = null; 5 | public var value:Any = null; 6 | } -------------------------------------------------------------------------------- /src/ast2obj/OConstantIdentifier.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OConstantIdentifier extends OExpression { 4 | public var name:String; 5 | } -------------------------------------------------------------------------------- /src/ast2obj/OExpression.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OExpression { 4 | public var prevExpression:OExpression = null; 5 | public var nextExpression:OExpression = null; 6 | 7 | public var id:Int; 8 | 9 | public function new() { 10 | } 11 | 12 | public function findPrev(type:Class):T { 13 | var p = prevExpression; 14 | var r = null; 15 | while (p != null && !Std.is(p, OBlock)) { 16 | if (Std.is(p, type)) { 17 | r = p; 18 | break; 19 | } 20 | 21 | if (Std.is(p, OBinOp)) { 22 | p = cast(p, OBinOp).expression; 23 | } else { 24 | p = p.prevExpression; 25 | } 26 | } 27 | return cast r; 28 | } 29 | } -------------------------------------------------------------------------------- /src/ast2obj/OFieldInstance.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OFieldInstance extends OExpression { 4 | public var cls:OClass; 5 | public var field:String; 6 | } -------------------------------------------------------------------------------- /src/ast2obj/OFieldStatic.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OFieldStatic extends OExpression { 4 | public var cls:OClass; 5 | public var field:String; 6 | } -------------------------------------------------------------------------------- /src/ast2obj/OIf.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OIf extends OExpression { 4 | public var conditionExpression:OExpression; 5 | public var ifExpression:OExpression; 6 | public var elseExpression:OExpression; 7 | } -------------------------------------------------------------------------------- /src/ast2obj/OLocal.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OLocal extends OExpression { 4 | public var name:String; 5 | public var type:OType; 6 | } -------------------------------------------------------------------------------- /src/ast2obj/OMethod.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OMethod { 4 | public var cls:OClass; 5 | 6 | public var type:OType; 7 | public var name:String; 8 | public var isStatic:Bool = false; 9 | public var expression:OExpression; 10 | public var args:Array = []; 11 | 12 | public function new() { 13 | } 14 | 15 | public function findMethodArg(id:Int):OMethodArg { 16 | var m = null; 17 | for (a in args) { 18 | if (a.id == id) { 19 | m = a; 20 | break; 21 | } 22 | } 23 | return m; 24 | } 25 | } -------------------------------------------------------------------------------- /src/ast2obj/OMethodArg.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OMethodArg { 4 | public var name:String; 5 | public var type:OType; 6 | public var value:OConstant; 7 | public var id:Int; 8 | 9 | public function new() { 10 | } 11 | } -------------------------------------------------------------------------------- /src/ast2obj/ONew.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class ONew extends OExpression { 4 | public var cls:OClass; 5 | public var expressions:Array = []; 6 | } -------------------------------------------------------------------------------- /src/ast2obj/OParenthesis.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OParenthesis extends OExpression { 4 | } -------------------------------------------------------------------------------- /src/ast2obj/OReturn.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OReturn extends OExpression { 4 | } -------------------------------------------------------------------------------- /src/ast2obj/OSwitch.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OSwitch extends OExpression { 4 | public var type:OType; 5 | public var expression:OExpression; 6 | public var cases:Array = []; 7 | public var defaultExpression:OExpression; 8 | } -------------------------------------------------------------------------------- /src/ast2obj/OThis.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OThis extends OExpression { 4 | } -------------------------------------------------------------------------------- /src/ast2obj/OType.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OType { 4 | public var name:String; 5 | public var typeParameters:Array = []; 6 | 7 | public function new() { 8 | } 9 | 10 | public var safeName(get, null):String; 11 | private function get_safeName():String { 12 | return StringTools.replace(name, ".", "_"); 13 | } 14 | } -------------------------------------------------------------------------------- /src/ast2obj/OTypeExprClass.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OTypeExprClass extends OExpression { 4 | public var cls:OClass; 5 | } -------------------------------------------------------------------------------- /src/ast2obj/OUnOp.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OUnOp extends OExpression { 4 | public var op:String; 5 | public var post:Bool; 6 | } -------------------------------------------------------------------------------- /src/ast2obj/OVar.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OVar extends OExpression { 4 | public var name:String; 5 | public var type:OType; 6 | } 7 | -------------------------------------------------------------------------------- /src/ast2obj/OWhile.hx: -------------------------------------------------------------------------------- 1 | package ast2obj; 2 | 3 | class OWhile extends OExpression { 4 | public var conditionExpression:OExpression; 5 | } -------------------------------------------------------------------------------- /src/ast2obj/builders/Compiler.hx: -------------------------------------------------------------------------------- 1 | package ast2obj.builders; 2 | import haxe.io.Path; 3 | import helpers.FileHelper; 4 | import helpers.ProcessHelper; 5 | import helpers.SizeHelper; 6 | import sys.FileSystem; 7 | 8 | class Compiler { 9 | private static var ARDUINO_HOME:String = "C:\\Program Files (x86)\\Arduino"; 10 | private static var ARDUINO_HOME_OSX:String = "/Applications/Arduino.app/Contents/Java"; 11 | 12 | private static var GCC:String = '"%ARDUINO_HOME%\\hardware\\tools\\avr/bin/avr-gcc"'; 13 | private static var GCCPP:String = '"%ARDUINO_HOME%\\hardware\\tools\\avr/bin/avr-g++"'; 14 | private static var GCC_AR:String = '"%ARDUINO_HOME%\\hardware\\tools\\avr/bin/avr-gcc-ar"'; 15 | private static var OBJCOPY:String = '"%ARDUINO_HOME%\\hardware\\tools\\avr/bin/avr-objcopy"'; 16 | private static var SIZE:String = '"%ARDUINO_HOME%\\hardware\\tools\\avr/bin/avr-size"'; 17 | 18 | private static var STD_INCLUDES:Array = [ 19 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino", 20 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\variants\\standard" 21 | ]; 22 | 23 | private static var ASM_CORE:Array = [ 24 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\wiring_pulse.S" 25 | ]; 26 | 27 | private static var C_CORE:Array = [ 28 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\wiring_shift.c", 29 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\wiring_pulse.c", 30 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\wiring_digital.c", 31 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\WInterrupts.c", 32 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\wiring_analog.c", 33 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\wiring.c", 34 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\hooks.c" 35 | ]; 36 | 37 | private static var CPP_CORE:Array = [ 38 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\CDC.cpp", 39 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\new.cpp", 40 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\Tone.cpp", 41 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\PluggableUSB.cpp", 42 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\HardwareSerial.cpp", 43 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\IPAddress.cpp", 44 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\Print.cpp", 45 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\HardwareSerial2.cpp", 46 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\abi.cpp", 47 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\HardwareSerial1.cpp", 48 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\Stream.cpp", 49 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\HardwareSerial0.cpp", 50 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\HardwareSerial3.cpp", 51 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\WString.cpp", 52 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\WMath.cpp", 53 | "%ARDUINO_HOME%\\hardware\\arduino\\avr\\cores\\arduino\\USBCore.cpp" 54 | ]; 55 | 56 | private static var CPP_FLAGS:String = "-c -w -Os -Wall -Wextra -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10807 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR"; 57 | private static var ASM_FLAGS:String = "-c -x assembler-with-cpp -flto -MMD -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10807 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR"; 58 | private static var C_FLAGS:String = "-c -Os -Wall -Wextra -std=gnu11 -ffunction-sections -fdata-sections -MMD -flto -fno-fat-lto-objects -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10807 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR"; 59 | private static var LINK_FLAGS:String = "-Wall -Wextra -Os -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p"; 60 | 61 | private static var NAME:String = "MyApp"; 62 | 63 | public static function compile(srcPath:String, includePath:String, outPath:String, libraries:Array = null) { 64 | haxe.Log.trace = function(v:Dynamic, ?infos:haxe.PosInfos) { 65 | Sys.println(v); 66 | } 67 | 68 | if (libraries == null) { 69 | libraries = []; 70 | } 71 | 72 | if (Sys.getEnv("ARDUINO_HOME") != null) { 73 | ARDUINO_HOME = Sys.getEnv("ARDUINO_HOME"); 74 | } else if (Sys.systemName() == "Mac") { 75 | ARDUINO_HOME = ARDUINO_HOME_OSX; 76 | } 77 | 78 | STD_INCLUDES.push(includePath); 79 | 80 | FileSystem.createDirectory(outPath); 81 | FileSystem.createDirectory(Path.normalize(outPath + "/core")); 82 | NAME = "MyApp"; // TODO: better way / name / does it matter? 83 | 84 | expandVars(); 85 | 86 | ///////////////////////////////////////////////////////////////////////////// 87 | // LIBRARIES 88 | ///////////////////////////////////////////////////////////////////////////// 89 | for (l in libraries) { 90 | if (FileSystem.exists(Path.normalize('${ARDUINO_HOME}/libraries/${l}/src'))) { 91 | FileHelper.copyFiles('${ARDUINO_HOME}/libraries/${l}/src', srcPath, "cpp"); 92 | FileHelper.copyFiles('${ARDUINO_HOME}/libraries/${l}/src', includePath, "h"); 93 | FileHelper.copyFiles('${ARDUINO_HOME}/libraries/${l}/src', includePath, "c"); 94 | } else if (FileSystem.exists(Path.normalize('${ARDUINO_HOME}/libraries/${l}'))) { 95 | FileHelper.copyFiles('${ARDUINO_HOME}/libraries/${l}', srcPath, "cpp"); 96 | FileHelper.copyFiles('${ARDUINO_HOME}/libraries/${l}', includePath, "h"); 97 | FileHelper.copyFiles('${ARDUINO_HOME}/libraries/${l}', includePath, "c"); 98 | } else if (FileSystem.exists(Path.normalize('${ARDUINO_HOME}/hardware/arduino/avr/libraries/${l}/src'))) { 99 | FileHelper.copyFiles('${ARDUINO_HOME}/hardware/arduino/avr/libraries/${l}/src', srcPath, "cpp"); 100 | FileHelper.copyFiles('${ARDUINO_HOME}/hardware/arduino/avr/libraries/${l}/src', includePath, "h"); 101 | FileHelper.copyFiles('${ARDUINO_HOME}/hardware/arduino/avr/libraries/${l}/src', includePath, "c"); 102 | } 103 | } 104 | 105 | ///////////////////////////////////////////////////////////////////////////// 106 | // COMPILATION 107 | ///////////////////////////////////////////////////////////////////////////// 108 | var cppFiles = []; 109 | FileHelper.findFiles(srcPath, "cpp", cppFiles); 110 | if (cppFiles.length == 0) { 111 | trace("NOTHING TO COMPILE!"); 112 | return; 113 | } 114 | 115 | var compilationFailed:Bool = false; 116 | for (cppFile in cppFiles) { 117 | var params:Array = CPP_FLAGS.split(" "); 118 | 119 | for (include in STD_INCLUDES) { 120 | params.push(Path.normalize('-I"${include}"')); 121 | } 122 | 123 | params.push(Path.normalize('"${cppFile}"')); 124 | params.push('-o'); 125 | params.push(Path.normalize('"${outPath}/${fileName(cppFile)}.o"')); 126 | var n = new ProcessHelper().run(Path.normalize(GCCPP), params); 127 | if (n != 0) { 128 | compilationFailed = true; 129 | break; 130 | } 131 | } 132 | 133 | if (compilationFailed == true) { 134 | trace("COMPILATION FAILED!"); 135 | return; 136 | } 137 | 138 | ///////////////////////////////////////////////////////////////////////////// 139 | // ASM CORE 140 | ///////////////////////////////////////////////////////////////////////////// 141 | compilationFailed = false; 142 | for (asmFile in ASM_CORE) { 143 | var params:Array = ASM_FLAGS.split(" "); 144 | 145 | for (include in STD_INCLUDES) { 146 | params.push(Path.normalize('-I"${include}"')); 147 | } 148 | 149 | params.push(Path.normalize('"${asmFile}"')); 150 | params.push('-o'); 151 | params.push(Path.normalize('"${outPath}/core/${fileName(asmFile)}.o"')); 152 | 153 | var n = new ProcessHelper().run(Path.normalize(GCC), params); 154 | if (n != 0) { 155 | compilationFailed = true; 156 | break; 157 | } 158 | } 159 | 160 | if (compilationFailed == true) { 161 | trace("ASM CORE COMPILATION FAILED!"); 162 | return; 163 | } 164 | 165 | ///////////////////////////////////////////////////////////////////////////// 166 | // C CORE 167 | ///////////////////////////////////////////////////////////////////////////// 168 | compilationFailed = false; 169 | for (cFile in C_CORE) { 170 | var params:Array = C_FLAGS.split(" "); 171 | 172 | for (include in STD_INCLUDES) { 173 | params.push(Path.normalize('-I"${include}"')); 174 | } 175 | 176 | params.push(Path.normalize('"${cFile}"')); 177 | params.push('-o'); 178 | params.push(Path.normalize('"${outPath}/core/${fileName(cFile)}.o"')); 179 | 180 | var n = new ProcessHelper().run(Path.normalize(GCC), params); 181 | if (n != 0) { 182 | compilationFailed = true; 183 | break; 184 | } 185 | } 186 | 187 | if (compilationFailed == true) { 188 | trace("C CORE COMPILATION FAILED!"); 189 | return; 190 | } 191 | 192 | ///////////////////////////////////////////////////////////////////////////// 193 | // CPP CORE 194 | ///////////////////////////////////////////////////////////////////////////// 195 | compilationFailed = false; 196 | for (cppFile in CPP_CORE) { 197 | var params:Array = CPP_FLAGS.split(" "); 198 | 199 | for (include in STD_INCLUDES) { 200 | params.push(Path.normalize('-I"${include}"')); 201 | } 202 | 203 | params.push(Path.normalize('"${cppFile}"')); 204 | params.push('-o'); 205 | params.push(Path.normalize('"${outPath}/core/${fileName(cppFile)}.o"')); 206 | 207 | var n = new ProcessHelper().run(Path.normalize(GCCPP), params); 208 | if (n != 0) { 209 | compilationFailed = true; 210 | break; 211 | } 212 | } 213 | 214 | if (compilationFailed == true) { 215 | trace("CPP CORE COMPILATION FAILED!"); 216 | return; 217 | } 218 | 219 | ///////////////////////////////////////////////////////////////////////////// 220 | // ARCHIVE 221 | ///////////////////////////////////////////////////////////////////////////// 222 | var oFiles = []; 223 | FileHelper.findFiles(Path.normalize('${outPath}/core'), "o", oFiles); 224 | for (oFile in oFiles) { 225 | var params:Array = ['rcs', Path.normalize('${outPath}/core/core.a'), oFile]; 226 | var n = new ProcessHelper().run(Path.normalize(GCC_AR), params); 227 | if (n != 0) { 228 | compilationFailed = true; 229 | break; 230 | } 231 | } 232 | 233 | if (compilationFailed == true) { 234 | trace("ARCHIVE FAILED!"); 235 | return; 236 | } 237 | 238 | ///////////////////////////////////////////////////////////////////////////// 239 | // LINK 240 | ///////////////////////////////////////////////////////////////////////////// 241 | var params:Array = LINK_FLAGS.split(" "); 242 | params.push('-o'); 243 | params.push(Path.normalize('${outPath}/${NAME}.elf')); 244 | for (cppFile in cppFiles) { 245 | params.push(Path.normalize('${outPath}/${fileName(cppFile)}.o')); 246 | } 247 | params.push(Path.normalize('${outPath}/core/core.a')); 248 | var n = new ProcessHelper().run(Path.normalize(GCC), params); 249 | if (n != 0) { 250 | trace("LINK FAILED!"); 251 | return; 252 | } 253 | 254 | ///////////////////////////////////////////////////////////////////////////// 255 | // OBJCOPY 1 256 | ///////////////////////////////////////////////////////////////////////////// 257 | var params:Array = "-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0".split(" "); 258 | params.push(Path.normalize('${outPath}/${NAME}.elf')); 259 | params.push(Path.normalize('${outPath}/${NAME}.eep')); 260 | var n = new ProcessHelper().run(Path.normalize(OBJCOPY), params); 261 | if (n != 0) { 262 | trace("OBJCOPY 1 FAILED!"); 263 | return; 264 | } 265 | 266 | ///////////////////////////////////////////////////////////////////////////// 267 | // OBJCOPY 2 268 | ///////////////////////////////////////////////////////////////////////////// 269 | var params:Array = "-O ihex -R .eeprom".split(" "); 270 | params.push(Path.normalize('${outPath}/${NAME}.elf')); 271 | params.push(Path.normalize('${outPath}/${NAME}.hex')); 272 | var n = new ProcessHelper().run(Path.normalize(OBJCOPY), params); 273 | if (n != 0) { 274 | trace("OBJCOPY 2 FAILED!"); 275 | return; 276 | } 277 | 278 | ///////////////////////////////////////////////////////////////////////////// 279 | // SIZE 280 | ///////////////////////////////////////////////////////////////////////////// 281 | var params:Array = "-A".split(" "); 282 | params.push(Path.normalize('${outPath}/${NAME}.elf')); 283 | var sizeHelper = new SizeHelper(Path.normalize(SIZE), params); 284 | sizeHelper.displayStats(); 285 | } 286 | 287 | private static function expandVars() { 288 | GCC = StringTools.replace(GCC, "%ARDUINO_HOME%", ARDUINO_HOME); 289 | GCCPP = StringTools.replace(GCCPP, "%ARDUINO_HOME%", ARDUINO_HOME); 290 | GCC_AR = StringTools.replace(GCC_AR, "%ARDUINO_HOME%", ARDUINO_HOME); 291 | OBJCOPY = StringTools.replace(OBJCOPY, "%ARDUINO_HOME%", ARDUINO_HOME); 292 | SIZE = StringTools.replace(SIZE, "%ARDUINO_HOME%", ARDUINO_HOME); 293 | 294 | for (a in 0...STD_INCLUDES.length) { 295 | STD_INCLUDES[a] = StringTools.replace(STD_INCLUDES[a], "%ARDUINO_HOME%", ARDUINO_HOME); 296 | } 297 | 298 | for (a in 0...ASM_CORE.length) { 299 | ASM_CORE[a] = StringTools.replace(ASM_CORE[a], "%ARDUINO_HOME%", ARDUINO_HOME); 300 | } 301 | 302 | for (a in 0...C_CORE.length) { 303 | C_CORE[a] = StringTools.replace(C_CORE[a], "%ARDUINO_HOME%", ARDUINO_HOME); 304 | } 305 | 306 | for (a in 0...CPP_CORE.length) { 307 | CPP_CORE[a] = StringTools.replace(CPP_CORE[a], "%ARDUINO_HOME%", ARDUINO_HOME); 308 | } 309 | } 310 | 311 | private static function fileName(f:String):String { 312 | var p = new Path(f); 313 | return p.file + "." + p.ext; 314 | } 315 | } 316 | -------------------------------------------------------------------------------- /src/ast2obj/builders/Installer.hx: -------------------------------------------------------------------------------- 1 | package ast2obj.builders; 2 | import firmware.hardware.MCU.MCUProvider; 3 | import haxe.io.Path; 4 | import helpers.ProcessHelper; 5 | import helpers.SizeHelper; 6 | 7 | class Installer { 8 | private static var ARDUINO_HOME:String = "C:\\PROGRA~2\\Arduino"; 9 | private static var ARDUINO_HOME_OSX:String = "/Applications/Arduino.app/Contents/Java"; 10 | 11 | private static var DUDE:String = '%ARDUINO_HOME%/hardware/tools/avr/bin/avrdude'; 12 | private static var SIZE:String = '%ARDUINO_HOME%/hardware/tools/avr/bin/avr-size'; 13 | 14 | public static function install(hexFile:String, ?port: String = null, ?speed: Null = null, ?board_code: String = null) { 15 | haxe.Log.trace = function(v:Dynamic, ?infos:haxe.PosInfos) { 16 | Sys.println(v); 17 | } 18 | 19 | if (Sys.getEnv("ARDUINO_HOME") != null) { 20 | ARDUINO_HOME = Sys.getEnv("ARDUINO_HOME"); 21 | } else if (Sys.systemName() == "Mac") { 22 | ARDUINO_HOME = ARDUINO_HOME_OSX; 23 | } 24 | 25 | if (board_code == null) { 26 | board_code = Sys.getEnv("TARGET_BOARD"); 27 | if (board_code == null) { 28 | trace("Error, provide 'TARGET_BOARD' env or '-boardcode' argument."); 29 | return; 30 | } 31 | } 32 | 33 | var board = MCUProvider.byCode(board_code); 34 | 35 | if (board == null) { 36 | trace('Error, board "$board_code" is not support.'); 37 | return; 38 | } 39 | 40 | if (speed == null) { 41 | speed = board.UploadingSpeed; 42 | } 43 | 44 | if (hexFile == null) { 45 | hexFile = Sys.getCwd() + "/build/hxArduino/out/MyApp.hex"; 46 | } 47 | 48 | expandVars(); 49 | hexFile = Path.normalize(hexFile); 50 | 51 | if (Sys.getEnv("ARDUINO_PORT") != null && port == null) { 52 | port = Sys.getEnv("ARDUINO_PORT"); 53 | } 54 | if (port == null) { 55 | trace("Error, provide 'ARDUINO_PORT' env or '-port' argument."); 56 | return; 57 | } 58 | 59 | trace("Installing: " + hexFile + " via " + port); 60 | var params:Array = '-C ${ARDUINO_HOME}/hardware/tools/avr/etc/avrdude.conf -v -p ${board.Name} -c${board.Protocol} -P${port} -b${speed} -D'.split(" "); 61 | params.push('-Uflash:w:${hexFile}:i'); 62 | var n = new ProcessHelper().run(DUDE, params); 63 | if (n != 0) { 64 | trace("INSTALL FAILED!"); 65 | Sys.getChar(false); 66 | return; 67 | } 68 | 69 | ///////////////////////////////////////////////////////////////////////////// 70 | // SIZE 71 | ///////////////////////////////////////////////////////////////////////////// 72 | var params:Array = "-A".split(" "); 73 | params.push(Path.normalize('${StringTools.replace(hexFile, ".hex", ".elf")}')); 74 | var sizeHelper = new SizeHelper(Path.normalize(SIZE), params); 75 | sizeHelper.displayStats(); 76 | } 77 | 78 | private static function expandVars() { 79 | DUDE = StringTools.replace(DUDE, "%ARDUINO_HOME%", ARDUINO_HOME); 80 | SIZE = StringTools.replace(SIZE, "%ARDUINO_HOME%", ARDUINO_HOME); 81 | } 82 | } -------------------------------------------------------------------------------- /src/ast2obj/builders/Monitor.hx: -------------------------------------------------------------------------------- 1 | package ast2obj.builders; 2 | 3 | import firmware.hardware.MCU.MCUProvider; 4 | 5 | class Monitor { 6 | public static function portlist() { 7 | haxe.Log.trace = function(v:Dynamic, ?infos:haxe.PosInfos) { 8 | Sys.println(v); 9 | } 10 | #if hxSerial 11 | var list = hxSerial.Serial.getDeviceList(); 12 | trace("Port list: " + list); 13 | var useport = ''; 14 | for (port in list){ 15 | var serialObj = new hxSerial.Serial(port, 115200); 16 | serialObj.setup(); 17 | 18 | var i = serialObj.available(); 19 | var s = serialObj.readBytes(i); 20 | neko.Lib.println ('\t- port: $port, available: $i, $s'); 21 | if(i>0) useport = port; 22 | } 23 | if(useport != ''){ 24 | trace('Use: haxelib run hxArduino --test -port $useport'); // I am guessing here, but it seems to work on osx 25 | } else { 26 | trace('Your guess is as good as mine; try to disconnect and run this command again and see the differences'); 27 | } 28 | #else 29 | trace("No hxSerial"); 30 | #end 31 | 32 | } 33 | public static function monitor(port:String = null, speed: Null, ?board_code: String = null) { 34 | haxe.Log.trace = function(v:Dynamic, ?infos:haxe.PosInfos) { 35 | Sys.println(v); 36 | } 37 | 38 | #if hxSerial 39 | 40 | if (Sys.getEnv("ARDUINO_PORT") != null && port == null) { 41 | port = Sys.getEnv("ARDUINO_PORT"); 42 | } 43 | if (port == null) { 44 | trace("Error, provide 'ARDUINO_PORT' env or '-port' argument."); 45 | return; 46 | } 47 | 48 | if (speed == null) { 49 | if (board_code == null) { 50 | board_code = Sys.getEnv("TARGET_BOARD"); 51 | if (board_code == null) { 52 | trace("Error, provide 'TARGET_BOARD' env or '-boardcode' argument."); 53 | return; 54 | } 55 | } 56 | var board = MCUProvider.byCode(board_code); 57 | if (board == null) { 58 | trace("cannot detect baudrate for connecting to serialport."); 59 | trace("Provide '-speed' argument or set 'TARGET_BOARD' env."); 60 | return; 61 | } 62 | speed = board.UploadingSpeed; 63 | } 64 | 65 | trace('Starting serial monitor on "$port" and "$speed" baudrate.'); 66 | trace("Port list: " + hxSerial.Serial.getDeviceList()); 67 | 68 | var serialObj = new hxSerial.Serial(port, speed); 69 | serialObj.setup(); 70 | 71 | while (true) { 72 | var i = serialObj.available(); 73 | if (i != 0) { 74 | Sys.print(serialObj.readBytes(i)); 75 | } 76 | Sys.sleep(0.01); 77 | } 78 | 79 | trace("Closing"); 80 | serialObj.close(); 81 | 82 | #else 83 | 84 | trace("No hxSerial"); 85 | 86 | #end 87 | } 88 | } -------------------------------------------------------------------------------- /src/firmware/hardware/AtMega2560.hx: -------------------------------------------------------------------------------- 1 | package firmware.hardware; 2 | 3 | import firmware.hardware.memory.*; 4 | 5 | class AtMega2560 implements MCU { 6 | public function new() { } 7 | 8 | public var UploadingSpeed(get, never): Int; 9 | 10 | public var Protocol(get, never): String; 11 | public var Name(get, never): String; 12 | 13 | public function get_Name(): String 14 | return "atmega2560"; 15 | 16 | public function get_Protocol(): String 17 | return "arduino"; 18 | 19 | public function get_UploadingSpeed(): Int 20 | return 115200; 21 | } -------------------------------------------------------------------------------- /src/firmware/hardware/AtMega328P.hx: -------------------------------------------------------------------------------- 1 | package firmware.hardware; 2 | 3 | import firmware.hardware.memory.*; 4 | 5 | class AtMega328P implements MCU { 6 | public function new() { } 7 | 8 | public var UploadingSpeed(get, never): Int; 9 | 10 | public var Protocol(get, never): String; 11 | public var Name(get, never): String; 12 | 13 | public function get_Name(): String 14 | return "atmega328p"; 15 | 16 | public function get_Protocol(): String 17 | return "arduino"; 18 | 19 | public function get_UploadingSpeed(): Int 20 | return 9600; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/firmware/hardware/MCU.hx: -------------------------------------------------------------------------------- 1 | package firmware.hardware; 2 | 3 | import firmware.hardware.*; 4 | import firmware.hardware.memory.*; 5 | 6 | interface MCU { 7 | public var UploadingSpeed(get, never): Int; 8 | 9 | public var Protocol(get, never): String; 10 | public var Name(get, never): String; 11 | } 12 | 13 | 14 | class MCUProvider { 15 | public static function byCode(code: String): Null { 16 | switch code.toLowerCase() { 17 | case "atmega328p": 18 | return new AtMega328P(); 19 | case "atmega2560": 20 | return new AtMega2560(); 21 | case "megaatmega2560": 22 | return new MegaAtMega2560(); 23 | case "nanoatmega328p": 24 | return new NanoAtMega328p(); 25 | case _: 26 | return null; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/firmware/hardware/MegaAtMega2560.hx: -------------------------------------------------------------------------------- 1 | package firmware.hardware; 2 | 3 | class MegaAtMega2560 extends AtMega2560 { 4 | public override function get_Protocol(): String 5 | return "wiring"; 6 | } -------------------------------------------------------------------------------- /src/firmware/hardware/NanoAtMega328p.hx: -------------------------------------------------------------------------------- 1 | package firmware.hardware; 2 | 3 | class NanoAtMega328p extends AtMega328P { 4 | public override function get_Name(): String 5 | return "atmega328p"; 6 | public override function get_UploadingSpeed(): Int 7 | return 57600; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /src/helpers/FileHelper.hx: -------------------------------------------------------------------------------- 1 | package helpers; 2 | 3 | import haxe.io.Path; 4 | import sys.FileSystem; 5 | import sys.io.File; 6 | 7 | class FileHelper { 8 | public static function findFiles(folder:String, extension:String, result:Array) { 9 | if (FileSystem.exists(folder) == false || FileSystem.isDirectory(folder) == false) { 10 | return; 11 | } 12 | 13 | var contents = FileSystem.readDirectory(folder); 14 | for (file in contents) { 15 | var fullPath = Path.normalize(folder + "/" + file); 16 | if (FileSystem.isDirectory(fullPath) == false && StringTools.endsWith(fullPath, '.${extension}')) { 17 | result.push(fullPath); 18 | } 19 | } 20 | 21 | for (file in contents) { 22 | var fullPath = Path.normalize(folder + "/" + file); 23 | if (FileSystem.isDirectory(fullPath) == true) { 24 | findFiles(fullPath, extension, result); 25 | } 26 | } 27 | } 28 | 29 | public static function copyFiles(src:String, dst:String, extension:String) { 30 | src = Path.normalize(src); 31 | var files:Array = []; 32 | findFiles(src, extension, files); 33 | for (f in files) { 34 | var relPath = StringTools.replace(f, src, ""); 35 | var dstPath = Path.normalize(dst + "/" + relPath); 36 | var p = new Path(dstPath); 37 | FileSystem.createDirectory(p.dir); 38 | File.copy(f, dstPath); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/helpers/HaxeLibHelper.hx: -------------------------------------------------------------------------------- 1 | package helpers; 2 | 3 | import sys.io.Process; 4 | 5 | class HaxeLibHelper { 6 | public static function getLibPath(lib:String):String { // pretty crappy way to do it i guess 7 | var path = null; 8 | 9 | var p = new Process("haxelib list"); 10 | var output = p.stdout.readAll().toString(); 11 | p.close(); 12 | 13 | for (line in output.split("\n")) { 14 | line = StringTools.trim(line); 15 | if (line.length == 0 || StringTools.startsWith(line, lib) == false) { 16 | continue; 17 | } 18 | 19 | var versions = line.split(" "); 20 | versions.shift(); 21 | for (v in versions) { 22 | if (StringTools.startsWith(v, "[") && StringTools.endsWith(v, "]")) { 23 | path = v.substr(1, v.length - 2); 24 | if (StringTools.startsWith(path, "dev:")) { 25 | path = path.substr(4, path.length); 26 | } else { 27 | path = getLibPathAlt(lib); 28 | } 29 | 30 | break; 31 | } 32 | } 33 | } 34 | 35 | return path; 36 | } 37 | 38 | private static function getLibPathAlt(lib:String):String { 39 | var path = null; 40 | 41 | var p = new Process("haxelib path " + lib); 42 | var output = p.stdout.readAll().toString(); 43 | p.close(); 44 | 45 | for (line in output.split("\n")) { 46 | line = StringTools.trim(line); 47 | if (line.length == 0 || StringTools.startsWith(line, "-") || StringTools.startsWith(line, "#")) { 48 | continue; 49 | } 50 | 51 | path = line; 52 | } 53 | 54 | return path + ".."; 55 | } 56 | 57 | public static function hasLib(lib:String):Bool { 58 | return (getLibPath(lib) != null); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/helpers/ProcessHelper.hx: -------------------------------------------------------------------------------- 1 | package helpers; 2 | 3 | /* 4 | import haxe.io.Eof; 5 | import haxe.io.Input; 6 | import neko.vm.Thread; 7 | */ 8 | import sys.io.Process; 9 | 10 | class ProcessHelper { 11 | public function new() { 12 | } 13 | 14 | public function run(command:String, args:Array):Int { 15 | trace('${command} ${args.join(" ")}'); 16 | var p = new Process('${command} ${args.join(" ")}'); 17 | 18 | 19 | /* 20 | var outThread = Thread.create(printStreamThread); 21 | outThread.sendMessage(p.stdout); 22 | 23 | var errThread = Thread.create(printStreamThread); 24 | errThread.sendMessage(p.stderr); 25 | */ 26 | 27 | var n:Int = p.exitCode(true); 28 | 29 | 30 | var so = StringTools.replace(p.stdout.readAll().toString(), "\r\n", "\n"); 31 | if (StringTools.trim(so).length > 0) { 32 | trace(StringTools.trim(so)); 33 | } 34 | var se = StringTools.replace(p.stderr.readAll().toString(), "\r\n", "\n"); 35 | if (StringTools.trim(se).length > 0) { 36 | trace(StringTools.trim(se)); 37 | } 38 | 39 | //p.close(); 40 | 41 | return n; 42 | } 43 | 44 | /* 45 | private function printStreamThread() { 46 | var stream:Input = Thread.readMessage(true); 47 | while (true) { 48 | try { 49 | var line = stream.readLine(); 50 | trace(line); 51 | } catch (e:Eof) { 52 | break; 53 | } catch (e:Dynamic) { 54 | trace(e); 55 | break; 56 | } 57 | } 58 | } 59 | */ 60 | } -------------------------------------------------------------------------------- /src/helpers/SizeHelper.hx: -------------------------------------------------------------------------------- 1 | package helpers; 2 | 3 | import sys.io.Process; 4 | 5 | class SizeHelper { 6 | private var _out:String; 7 | public function new(command:String, args:Array) { 8 | if (args == null) { 9 | args = []; 10 | } 11 | 12 | trace('${command} ${args.join(" ")}'); 13 | var p = new Process('${command} ${args.join(" ")}'); 14 | p.exitCode(true); 15 | 16 | var so = StringTools.replace(p.stdout.readAll().toString(), "\r\n", "\n"); 17 | if (StringTools.trim(so).length > 0) { 18 | _out = StringTools.trim(so); 19 | } 20 | } 21 | 22 | public function displayStats() { 23 | if (_out == null) { 24 | return; 25 | } 26 | 27 | var lines = _out.split("\n"); 28 | var data:Int = 0; 29 | var text:Int = 0; 30 | var bss:Int = 0; 31 | 32 | // UNO sizes: 33 | var program_storage_max:Int = 32256; 34 | var global_max:Int = 2048; 35 | // METRO sizes: 36 | // var program_storage_max:Int = 524288; 37 | // var global_max:Int = 196608; 38 | 39 | for (l in lines) { 40 | l = StringTools.trim(l); 41 | if (StringTools.startsWith(l, ".data")) { 42 | data = extractStat(StringTools.replace(l, ".data", "")); 43 | } else if (StringTools.startsWith(l, ".text")) { 44 | text = extractStat(StringTools.replace(l, ".text", "")); 45 | } else if (StringTools.startsWith(l, ".bss")) { 46 | bss = extractStat(StringTools.replace(l, ".bss", "")); 47 | } 48 | } 49 | 50 | trace(_out); 51 | 52 | var program_storage_used = (text / program_storage_max) * 100; 53 | trace("\nProgram storage usage: " + Math.fround(program_storage_used) + "%"); 54 | var global_storage_used = ((data + bss) / global_max) * 100; 55 | trace("Global variable usage: " + Math.fround(global_storage_used) + "%\n"); 56 | } 57 | 58 | private function extractStat(l:String):Int { 59 | l = StringTools.trim(l); 60 | var x:String = l.split(" ")[0]; 61 | 62 | return Std.parseInt(x); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /submit.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | del hxArduino.zip /q 4 | 7za a hxArduino.zip extraParams.hxml haxelib.json run.n lib src 5 | 6 | haxelib submit hxArduino.zip ianharrigan 7 | del hxArduino.zip /q 8 | --------------------------------------------------------------------------------