Haxe - The Cross-Platform Toolkit

Overview

GitHub Build Status SauceLabs Test Status Gitter Discord

Haxe is an open source toolkit that allows you to easily build cross-platform tools and applications that target many mainstream platforms. The Haxe toolkit includes:

  • The Haxe programming language, a modern, high-level, strictly-typed programming language
  • The Haxe cross-compiler, a state-of-the-art, lightning-speed compiler for many targets
  • The Haxe standard library, a complete, cross-platform library of common functionality

Haxe allows you to compile for the following targets:

You can try Haxe directly from your browser at try.haxe.org!

For more information about Haxe, head to the official Haxe website.

License

The Haxe project has several licenses, covering different parts of the projects.

  • The Haxe compiler is released under the GNU General Public License version 2 or any later version.
  • The Haxe standard library is released under the MIT license.
  • The Neko virtual machine is released under the MIT license. Its bundled runtime libraries (ndll) and tools are released under open source licenses as described in https://github.com/HaxeFoundation/neko/blob/master/LICENSE

For the complete Haxe licenses, please see https://haxe.org/foundation/open-source.html or extra/LICENSE.txt.

Installing Haxe

The latest stable release is available at https://haxe.org/download/. Pre-built binaries are available for your platform:

Automated development builds are available from build.haxe.org.

Building from source

See extra/BUILDING.md.

Using Haxe

For information on using Haxe, consult the Haxe documentation:

Community

You can get help and talk with fellow Haxers from around the world via:

👍 Get notified of the latest Haxe news, follow us on Twitter, Facebook and don't forget to read the Haxe roundups.

Version compatibility

Haxe Neko SWF Python HL PHP Lua
2.* 1.* 8-10 - - - -
3.0.0 2.0.0 - - 5.1+ -
3.2.0 12-14 3.2+ - -
3.3.0 2.1.0 21 - 5.1, 5.2, 5.3, LuaJIT 2.0, 2.1
3.4.0 1.1 5.4+ and 7.0+ (with -D php7)
4.0.0 2.3.0 1.11 7.0+

Contributing

See CONTRIBUTING.md for more. Thank you!

Comments
  • Short Lambdas

    Short Lambdas

    Arrow functions as per ES6

    // Basic syntax:
    (param1, param2, paramN) => { statements }
    (param1, param2, paramN) => expression
       // equivalent to:  => { return expression; }
    
    // Parentheses around the single argument are not required:
    singleParam => { statements }
    singleParam => expression
    
    // Function with no arguments requires parentheses:
    () => { statements }
    
    opened by dpeek 165
  • Add node.js implementation to std

    Add node.js implementation to std

    This issue report is to start a discussion about whether it would be a good idea to implement the node.js library as part of haxe std.

    Node.js can be considered a very useful technology, and I see that its use has been growing a lot in the Haxe community. We have some problems with the current state of affairs now, however:

    • Synchronization between haxe std files and nodejs libraries - many libraries need to change some std Haxe files to provide e.g. the nodejs way to deal with bytes and streams. These changes into core may get out of sync if we don't maintain it in the same place
    • Try to unify all the scattered implementations / forks, in a place where we can be certain to maintain them
    • Add a specific travis target for node.js, so we can make sure we don't break anything there as well

    Thoughts?

    discussion 
    opened by waneck 146
  • Std Main Loop

    Std Main Loop

    Each platform comes with its own “main event loop” implementation, making it hard to build crossplatform API over it.

    We shoul provide a base abstract loop definition that can help this.

    Discussion opened on the topic.

    discussion 
    opened by ncannasse 115
  • [js] support creating extern classes by calling a constructor function without

    [js] support creating extern classes by calling a constructor function without "new" keyword

    See https://github.com/HaxeFoundation/haxe/issues/2784#issuecomment-57943535

    It seems that it's quite common in JS libraries that objects are created by simply calling a function instead of using "new SomeConstructor" syntax (e.g. JQuery, express, socket.io), so I think it makes sense for us to support that.

    The most straightforward way is probably to use metadata for the constructor field that simply makes JS generator omit the new keyword, i.e.

    extern Express {
        @:noNew // we need a better name for it
        function new();
    }
    

    But I don't really know to what extent is it compatible with e.g. Type.createInstance. @aduros, @clemos, @eduardo-costa any comments?

    enhancement platform-javascript 
    opened by nadako 73
  • Issue 1138 - Defaults - haxe

    Issue 1138 - Defaults - haxe

    [Google Issue #1138 : https://code.google.com/p/haxe/issues/detail?id=1138] by [email protected], at 09/08/2012, 13:03:21 Have a special file named "defaults.hx" (lowercase to differentiate from normal file ?) which contains :

    • type definitions globally accessible
    • "import" which are done by default
    • "using" which are done by default

    This file will apply to the package it is defined into and to all its sub packages. Defaults can shadow each other definitions the normal way.

    • a haxelib library can also have its own "defaults.hx" which activates itself when the user link the library with -lib (less priority than project-specific defaults)
    • it is possible to specify additional (project-whole) defaults files by commandline (for configuration for instance)

    To prevent conflicts :

    • defaults of the project does not apply to libraries
    • defaults of one library does not apply to other libraries (except if there is a dependency ? - hard to tell/implement)
    opened by issuesbot 65
  • Request for feature: eliminate singly-implemented interfaces

    Request for feature: eliminate singly-implemented interfaces

    In our large code base, a considerable amount of code can be eliminated from the runtime, with corresponding size benefits, if the haxe compiler could perform this optimization:

    • After all types have been parsed, look for interfaces that have only one class implementing them. For such an interface IA implemented by a single class A, replace all type occurrences of IA throughout the AST by A.

    In other words, turn all references to "interfaces implemented by a single class" into "the single class".

    These interfaces would then never be seen by the compiler back end code and could contribute nothing to the eventual application size.

    Our application has ~3260 interfaces, of which ~1260 would be eliminated by this optimization. Since interfaces have a code cost for all backends, and an especially onerous cost for the hxcpp backend, eliminating these interfaces would save us a good deal of binary size.

    Furthermore, the cost of the dynamically bound call through an interface function is significant, and if such interfaces are eliminated and replaced by the class that implements them, then the function call themselves can be much more efficient, for backends such as hxcpp and hxjava.

    opened by bjitivo 61
  • Use abstract instead of typedef for `Null<T>`

    Use abstract instead of typedef for `Null`

    For the most part this changes some TType to TAbstract and moves match cases around where necessary. There are a few special cases in type.ml to retain the current behavior and not break anything.

    The idea is this:

    1. Merge this and stabilize it (now).
    2. Add a compiler flag to remove the to T from Null<T> and provide some sort of .force():T field (for 3.3.0).
    3. Get rid of the special cases that allow e.g. variance of Array<Int> and Array<Null<Int>> (for Haxe 4.0.0).

    This PR might break macros that check for TType("Null") right now. However, we have plenty of time to communicate that before the next release so it shouldn't be a problem.

    @ncannasse: If you have any reservations about doing this please speak up now. I would like to merge this really soon because it's quite merge-conflict-vulnerable.

    opened by Simn 61
  • case <var> syntax change

    case syntax change

    One thing I often have to explain about Haxe to new developers are the case ident: that is actually a default when the pattern ident is unmatched.

    It currently gives a warning but that's not very straightforward to understand that it's a actually a catch-all case, and can often lead to code with wrong behavior.

    I propose removing this, forcing "case" to always be a not-single-var pattern (at least when there's no guard), and instead allow default ident: (ident being optional) which gives a better understanding that it's actually a catch-all case.

    opened by ncannasse 58
  • null casting inconsistent behaviour

    null casting inconsistent behaviour

    There seems to be different semantic for casting null in haxe cpp. The following will throw an error in Js and Neko but not in Cpp

    cast(null, MyClass);
    

    Note that if I cast primitive types (String, Int...), Js, Neko and Cpp all throw an error. I didn't try other targets. I'm using Haxe 3.1.2.

    This could be fixed in 2 ways:

    • Allow null casting on all types. Java does that.
    • Prevent casting null to an object in haxe cpp.

    What do you think ?

    opened by yanhick 56
  • Object requires field iterator (ufront TemplateData)

    Object requires field iterator (ufront TemplateData)

    package;
    
    import haxe.ds.StringMap;
    using StringTools;
    
    class Main {
    
        public static function main()
        {
            var d:TemplateData = {};
        }
    
    }
    
    
    
    abstract TemplateData({}) from {} to {} {
    
        /**
        Create a template data object.
    
        @param obj The object to use.  If null a new TemplateData object with no values will be used.
        **/
        public inline function new( ?obj:{} )
            this = (obj!=null) ? obj : {};
    
        /**
        Convert into a `Dynamic<Dynamic>` anonymous object.
        Please note this is not an implicit `@:to` cast, because the resulting type would match too many false positives.
        To use this cast call `templateData.toObject()` explicitly.
        **/
        public inline function toObject():Dynamic<Dynamic>
            return this;
    
        /**
        Convert into a `Map<String,Dynamic>`.
        This is also available as an implicit `@:to` cast.
        **/
        @:to public function toMap():Map<String,Dynamic> {
            var ret = new Map<String,Dynamic>();
            for ( k in Reflect.fields(this) ) ret[k] = Reflect.field( this, k );
            return ret;
        }
    
        /**
        Convert into a `StringMap<Dynamic>`.
        This is also available as an implicit `@:to` cast.
        **/
        @:to public inline function toStringMap():StringMap<Dynamic> {
            return toMap();
        }
    
        /**
        Get a value from the template data.
    
        This is also used for array access: `templateData['name']` is the same as `templateData.get('name')`.
    
        @param key The name of the value to retrieve.
        @return The value, or null if it was not available.
        **/
        @:arrayAccess public inline function get( key:String ):Null<Dynamic> return Reflect.field( this, key );
    
        /**
        See if a specific field exists in the template data.
        **/
        public function exists( key:String ):Bool {
            return Reflect.hasField( this, key );
        }
    
        /**
        Set a value on the template data.
    
        Please note array setters are also available, but they use the private `array_set` method which returns the value, rather than the TemplateData object.
    
        @param key The name of the key to set.
        @param val The value to set.
        @return The same TemplateData so that method chaining is enabled.
        **/
        public function set( key:String, val:Dynamic ):TemplateData {
            Reflect.setField( this, key, val );
            return new TemplateData( this );
        }
    
        /** Array access setter. **/
        @:arrayAccess function array_set<T>( key:String, val:T ):T {
            Reflect.setField( this, key, val );
            return val;
        }
    
        /**
        Set many values from a `Map<String,Dynamic>`
    
        `templateData.set(key,map[key])` will be called for each pair in the map.
    
        @param map The map data to set.
        @return The same TemplateData so that method chaining is enabled.
        **/
        public function setMap<T>( map:Map<String,T> ):TemplateData {
            for ( k in map.keys() ) {
                set( k, map[k] );
            }
            return new TemplateData( this );
        }
    
        /**
        Set many values from an object.
    
        `templateData.set(fieldName,fieldValue)` will be called for each field or property on the object.
    
        The behaviour differ depending on if this is an anonymous object or a class instance:
    
        - Anonymous objects will find all fields using `Reflect.fields()` and fetch the values using `Reflect.field()`.
        - Class instance objects will find all fields using `Type.getInstanceFields()` and fetch the values using `Reflect.getProperty()`.
        - Other values will be ignored.
    
        Please note on PHP, objects that are class instances may fail to load fields that are functions.
    
        @param d The data object to set.
        @return The same TemplateData so that method chaining is enabled.
        **/
        public function setObject( d:{} ):TemplateData {
            switch Type.typeof(d) {
                case TObject:
                    for ( k in Reflect.fields(d) ) set( k, Reflect.field(d,k) );
                case TClass(cls):
                    #if php
                        // PHP can't access properties on class instances using Reflect.getProperty, it throws an error.
                        // These checks and fallbacks are not required on JS or neko. It might be good to submit a bug report.
                        for ( k in Type.getInstanceFields(cls) ) {
                            try set( k, Reflect.getProperty(d,k) )
                            catch ( e:Dynamic ) try set( k, Reflect.field(d,k) )
                            catch ( e:Dynamic ) {}
                        }
                    #else
                        for ( k in Type.getInstanceFields(cls) ) set( k, Reflect.getProperty(d,k) );
                    #end
                case _:
            }
            return new TemplateData( this );
        }
    
        /** from casts **/
    
        /**
        Automatically cast from a `Map<String,Dynamic>` into a TemplateData.
        **/
        @:from public static function fromMap<T>( d:Map<String,T> ):TemplateData {
            var m:TemplateData = new TemplateData( {} );
            m.setMap( d );
            return m;
        }
    
        /**
        Automatically cast from a `StringMap<Dynamic>` into a TemplateData.
        **/
        @:from public static inline function fromStringMap<T>( d:StringMap<T> ):TemplateData {
            return fromMap( d );
        }
    
        /**
        Automatically cast from a `Iterable<TemplateData>` into a combined `TemplateData.
    
        Values will be added in order, and later values with the same name as an earlier value will override the earlier value.
    
        If the iterable is empty, the resulting TemplateData will contain no properties.
    
        If an individual item is a StringMap, it will be added with `setMap`, otherwise it will be added with `setObject`.
    
        @param dataSets The collection of TemplateData objects to iterate over.
        @return The same TemplateData so that method chaining is enabled.
        **/
        @:from public static function fromMany( dataSets:Iterable<TemplateData> ):TemplateData {
            var combined:TemplateData = new TemplateData( {} );
            for ( d in dataSets ) {
                if ( d!=null ) {
                    if ( Std.is(d,StringMap) ) {
                        var map:StringMap<Dynamic> = cast d;
                        combined.setMap( (map:StringMap<Dynamic>) );
                    }
                    else {
                        var obj:Dynamic = d;
                        combined.setObject( obj );
                    }
                }
            }
            return combined;
        }
    
        /**
        Automatically cast from an object to a TemplateData.
    
        This results in a new object, the equivalent of calling `new TemplateData().setObject( d )`.
    
        This cast comes last in the code so it should be used only if none of the other casts were utilised.
        **/
        @:from public static inline function fromObject( d:{} ):TemplateData {
            return null ; //new TemplateData( {} ).setObject( d );
        }
    }
    

    This does not work on latest build (3d001e0) but had been working in 3.2.1.

    regression 
    opened by kevinresol 55
  • macros and type building issue

    macros and type building issue

    I can't compile my work project codebase after commit eca310eac210fc3379ef560ab3fd22c20fc6344b, it says that it can't find a field which is a macro method. I'll try to reduce it to a reproducible example, but it won't be easy because the code involved is complex.

    priority-urgent regression 
    opened by nadako 55
  • Regex stack overflow in Neko/HL

    Regex stack overflow in Neko/HL

    In my quest to write the most cursed regexes, I found one that breaks on moderately sized strings.

    This looks to be an issue in the regex libs itself, though I'm filing here as a first point of contact, since I don't have a good way to test if it's due to some shenanigans on our end or not.

    Test case:

    class Test {
      static function main() {
        var r = ~/\/\*(((?!\*\/).)*)$/s;
        var a = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
        
        var test = "/*";
        for( i in 0 ... 10 )
        {
          test += a;
          trace( 'iter $i: ${r.match(test)}');    
        }
        
        trace( "Finished");
      }
    }
    

    Or if you prefer, a try.haxe link: https://try.haxe.org/#cAfb5b04

    This code works fine in Javascript and python, I've not tested other platforms yet. However, both Neko and HL fail (Neko simply aborts, Hashlink throws an unrecoverable stack overflow exception.

    If you wind down the iterations it'll succeed, so it's limited to longer string lengths.

    opened by nspitko 1
  • DCE shouldn't remove static calls to impure functions (fixes #10433)

    DCE shouldn't remove static calls to impure functions (fixes #10433)

    There are some missing @:pure annotations in the std lib, which I noticed after fixing this as some unnecessary static vars would now be preserved. Fixed the ones I noticed.

    Fixes #10433

    opened by bendmorris 2
  • Missing `return` ignored after short-circuited `throw`

    Missing `return` ignored after short-circuited `throw`

    class Main {
      public static function main():Void trace(foo());
      public static function foo():Int {
        true || throw 0;
        0;
      }
    }
    

    foo should return an integer but it does not: the trace outputs null (on Eval). If I remove the true || throw 0 line, the error "Missing return: Int" is triggered as expected. I can also use false && throw 0. I wonder if this is related to #10791 (or a similar analysis).

    opened by Aurel300 1
  • Pretty errors

    Pretty errors

    Adds an optional alternative error reporting mode, adding more contextual information to errors (sources) for example like that:

    image

    This should only apply when -D pretty-errors is set, thus not impacting existing tools relying on current output. Additionally, -D no-color can be used if your terminal doesn't support ANSI escape codes:

    image

    Note that some cases are not supported yet, mostly interp errors and some stack errors. Non exhaustive TODO list:

    • [ ] Add nesting level to macro message API
    • [ ] Handle interp errors (might need a rework of interp errors (relying on string building right now, and losing context needed by verbose error reporting)
    • [ ] Handle nesting level in some more cases if misbehavior is spotted
    • [ ] Cleanup the code, it's very POC-like for now
    • [ ] Add some tests for verbose error output

    Showcase of current status: https://asciinema.org/a/ehYMIcPtW1eV26YNo9F9krYq4 (with 9ebc710)

    Grab nightlies to try it out (updated to 9ebc710):

    opened by kLabz 4
  • [CPP] Build error when building classes extending abstracts.

    [CPP] Build error when building classes extending abstracts.

    When building certain abstract classes on CPP (I was using Lime on Windows), an incorrect class is sometimes generated.

    Copying my reproduction from vegardit/haxe-concurrent#22:

    • Install Lime via Haxelib (haxelib install lime)
    • Create a minimal Lime sample project (lime create HelloWorld)
    • Open project.xml and add the haxelib (<haxelib name="haxe-concurrent" />)
    • Add code to Main.hx to use the library (I simply added code which instantiates a RLock and nothing else)
    • Attempt to build the project (lime build windows)

    The results:

    • When using v3.0.2 of haxe-concurrent (which does not include abstract classes) compilation works fine.
    • When using v4.0.0 of haxe-concurrent (this version was reworked to include abstract classes) compilation fails, claiming RLock is not implementing tryAcquire().
    • Enabling full Dead-Code-Execution (<haxeflag name="-dce" value="full" />) compilation works fine (even if tryAcquire() is being called).

    Further discussion, build logs, and the repo where I reproduced the issue can be found at the linked issue.

    opened by MasterEric 0
Releases(4.2.5)
Owner
Haxe Foundation
Haxe Foundation
The Leap Motion cross-format, cross-platform declarative serialization library

Introduction to LeapSerial LeapSerial is a cross-format, declarative, serialization and deserialization library written and maintained by Leap Motion.

Leap Motion (Ultraleap) 15 Jan 17, 2022
A cross platform shader language with multi-threaded offline compilation or platform shader source code generation

A cross platform shader language with multi-threaded offline compilation or platform shader source code generation. Output json reflection info and c++ header with your shaders structs, fx-like techniques and compile time branch evaluation via (uber-shader) "permutations".

Alex Dixon 285 Nov 16, 2022
Cross-platform C++11 header-only library for memory mapped file IO

mio An easy to use header-only cross-platform C++11 memory mapping library with an MIT license. mio has been created with the goal to be easily includ

null 1.4k Nov 26, 2022
Cross-platform, Serial Port library written in C++

Serial Communication Library (Linux and OS X) (Windows) This is a cross-platform library for interfacing with rs-232 serial like ports written in C++.

William Woodall 1.7k Nov 30, 2022
Collection of cross-platform single-header C libraries for doing a lot of stuff! (Still WIP)

ice_libs Collection of cross-platform single-header C libraries for doing a lot of stuff! (Still WIP) Brief ice_libs is collection of Single-Header C

Rabia Alhaffar 117 Dec 2, 2022
A cross-platform (Android/iOS/Windows/macOS) cronet plugin for Flutter via `dart:ffi`

cronet_flutter A cross-platform (Android/iOS/Windows/macOS) cronet plugin for Flutter via dart:ffi

null 24 Nov 9, 2022
Cross-platform tool to extract wavetables and draw envelopes from sample files, exporting the wavetable and generating the appropriate SFZ text to use in a suitable player.

wextract Cross-platform tool to extract wavetables and draw envelopes from sample files, exporting the wavetable and generating the appropriate SFZ te

Paul Ferrand 9 Jan 5, 2022
Freeze OS is a cross-platform operating system emulator that runs on top of an interpreter called the Freeze interpreter.

Freeze OS is a cross-platform operating system emulator that runs on top of an interpreter called the Freeze interpreter. The operating system code is basically written in the Freeze programming language that is passed to the Freeze interpreter. The idea is to skip instances where the operating system needs to handle low level operators and focus on higher level stuff, like malware analysis, AI, and others.

null 24 May 2, 2022
Khepri is a Cross-platform agent, the architecture and usage like Coblat Strike but free and open-source.

Khepri Free,Open-Source,Cross-platform agent and Post-exploiton tool written in Golang and C++ Description Khepri is a Cross-platform agent, the archi

Young 1.4k Nov 24, 2022
JWM is a cross-platform Java window management and OS integration library.

JWM aims to expose an interface that abstracts over window creation, input handling and OS integration

JetBrains 371 Nov 23, 2022
Free,Open-Source,Cross-platform agent and Post-exploiton tool written in Golang and C++, the architecture and usage like Cobalt Strike

Khepri Free,Open-Source,Cross-platform agent and Post-exploiton tool written in Golang and C++ Description Khepri is a Cross-platform agent, the archi

Young 1.4k Nov 20, 2022
FireDog - Open source cross-platform lightweight virus signature detection engine.

FireDog 开源跨平台轻量级病毒特征检测引擎。Open source cross-platform lightweight virus signature detection engine. 语言 Language C++ 11 LICENSE 是你们喜欢的:MIT License. 让我们搞起

null 41 Nov 4, 2022
A cross-platform flutter plugin for C/C++/ObjC crash report via Google Breakpad

quick_breakpad A cross-platform flutter plugin for C/C++/ObjC crash report via Google Breakpad Use breakpad for quick_breakpad_example $CLI_BREAKPAD i

Woodemi Co., Ltd 16 Jul 30, 2022
SDR++ is a cross-platform and open source SDR software with the aim of being bloat free and simple to use.

SDR++ is a cross-platform and open source SDR software with the aim of being bloat free and simple to use.

AlexandreRouma 2.1k Nov 24, 2022
First open-source Geometry Dash cross-platform Modding SDK

BoolkaSDK First open-source Geometry Dash cross-platform Modding SDK Requirements CMake 3.21 Android NDK r23 LLVM x86 Java and ApkTool Building Open C

null 7 Nov 20, 2022
an easy-to-use cross platform web browser controller for C++

WebBrowser++ 这是一个基于C++17的唯头文件跨平台浏览器控制库。 您只需要将本目录下的Include文件夹拷贝至您的项目中即可使用。如果使用CMake编译,则可直接include_directories(Include),也可以模仿本项目的CMakeLists.txt进行编写。 建立该

null 8 Nov 17, 2021
A fully-featured, cross platform XO-CHIP/S-CHIP/CHIP-8 emulator written in C and SDL.

JAXE (Just Another XO-CHIP/CHIP-8 Emulator) Brix Space Invaders (In Debug Mode) Black Rainbow DVN8 Super Neat Boy Chicken Scratch CHIP-8 was a virtual

Kurtis Dinelle 21 Nov 12, 2022
Appupdater is a C++ cross-platform framework to update desktop software (gitlab mirror)

appupdater is a C++ cross-platform framework to update desktop software. How it works Framework checks the URL you specified for info about versions a

Ronzhin Mikhail 1 Jan 8, 2022
Simple, cross-platform library to handle multiple mice.

ManyMouse ManyMouse's website is https://icculus.org/manymouse/ This is a simple library to abstract away the reading of multiple input devices. It is

Ryan C. Gordon 32 Nov 17, 2022