Aleksey Fomkin avatar Aleksey Fomkin committed f582fea

new java reading way

Comments (0)

Files changed (22)

--main com.yarrcad.cg.CodeGenerator
+-main com.yelbota.cgml.CodeGenerator
 -cp src
 -java bin/java 
 #-neko bin/cgmlc.n

res/lang.basic.cgml

 > basic
 . void int64 # Знаковый 0xFFFFFFFFFFFFFFFF
 > basic
-. void float # Знаковый 0xFFFFFFFF.FFFFFFFF
+. void double # Знаковый 0xFFFFFFFF.FFFFFFFF
 
 > basic
 . void ubyte  # Баззнаковый 0xFF

src/com/yarrcad/cg/Ast.hx

-/*
- * This file is part of the CGML Compiler
- *
- * Copyright(c) 2005-2010 Aleksey Fomkin <aleksey.fomkin@gmail.com>
- * http://bitbucket.org/yelbota/cgml-compiler
- *
- * This file may be licensed under the terms of of the
- * GNU General Public License Version 3 (the ``GPL'').
- *
- * Software distributed under the License is distributed
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
- * express or implied. See the GPL for the specific language
- * governing rights and limitations.
- *
- * You should have received a copy of the GPL along with this
- * program. If not, go to http://www.gnu.org/licenses/gpl.html
- * or write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-package com.yarrcad.cg;
-
-import haxe.FastList;
-import com.yarrcad.cg.Cgml;
-
-class Ast
-{
-  /**
-   * Хеш типов.
-   */
-  public var types(default, null):Hash<Node>;
-
-  public var typesByNs:Hash<List<Node>>;
-  
-
-  /**
-   *  Virtual generics.
-   */
-  private var vgTypes:Hash<{t1:Node, t2: Node, t3:Node, ns:String}>;
-  private var vgFilled:IntHash<Bool>;
-
-  /**
-   *  Хитрый хеш в котором лежат пространства имен заюзаные для модуля. 
-   *  Как-то так uses.get([module ns]) == FastList<[ns]>.
-   */
-  public var uses(default, null):Hash<FastList<String>>;
-
-  public function new(cgmls:Array<Cgml>, defines:List<String>)
-  {
-    types = new Hash<Node>();
-    vgTypes = new Hash();
-    typesByNs = new Hash();
-    vgFilled = new IntHash();
-    uses = new Hash<FastList<String>>();
-    
-    // Для начала надо узнать какие типы есть вообще. По этому создадим все типы
-    // по именам не заморачиваясь над их сутью.
-    for (cgml in cgmls)
-    {
-      for (c in cgml.nodes)
-      {
-        switch (c)
-        {
-          case Annotation(an):
-          {
-            // do nothing
-          }
-          case Namespace(ns):
-          {
-            //trace("cgml.filename = " + cgml.filename);
-            var nslist = uses.get(cgml.ns);
-            //trace("Namespace " +cgml.ns+ " imports " + ns);
-            if (nslist == null)
-            {
-              nslist = new FastList<String>();
-              uses.set(cgml.ns, nslist);
-            }
-            
-            nslist.add(ns);
-          }
-          case Declaration(dec):
-          {
-            if (getType(cgml.ns, dec.name) != null)
-              throw Cgml.errorLine(dec) + "Duplicate type \"" + dec.name + "\"";
-
-            var type = switch (dec.key)
-            {
-              case Variant: Variant(new Variant(dec.name, cgml.ns, false));
-              case Model: Model(new Model(dec.name, cgml.ns,false, false));
-              case FinalModel: Model(new Model(dec.name,cgml.ns,true, false));
-              case TypedModel: Model(new Model(dec.name,cgml.ns,false, true));
-              case TypedVariant: Variant(new Variant(dec.name, cgml.ns, true));
-              default: throw "Internal error.";
-            }
-            
-            // Новый тип в дерево типов.
-            setType(type);
-          }
-        }
-      }
-    }
-    
-    // Теперь, когда нам известно, какие типы есть в нашем распоряжении
-    // мы можем сделать боле подробный анализ первичного дерева.
-    for (cgml in cgmls)
-    {
-      for (c in cgml.nodes)
-      {
-        switch (c)
-        {
-          case Namespace(_), Annotation(_):
-          {
-            // Ничего не делаем.
-          }
-          case Declaration(dec):
-          {
-            switch (types.get(getTypenameForNs(cgml.ns, dec.name)))
-            {
-              case Model(model):
-              {
-                var type = getTypeByCgmlDec(cgml, dec, dec.type);
-                
-                switch (type)
-                {
-                  case Variant(v): throw Cgml.errorLine(dec) + 
-                    "Model can't extends variant";
-                  case Model(m):
-                  {
-                    if (m.final) throw Cgml.errorLine(dec)+
-                      "Model can't extends final type";
-                      
-                    //if (model.typed && !m.typed) throw Cgml.errorLine(dec)+
-                    //  "Generic can't extends solid model"; 
-                  }
-                  case T: if (!model.typed) throw Cgml.errorLine(dec)+
-                    "Can't use \"t\" instade solid model";
-                  default: {};
-                }
-
-                model.type = type;
-                model.annotations = preprocessAnnotations(dec.annotations, defines);
-                
-                for (cdec in dec.children)
-                {
-                  var propType = getTypeByCgmlDec(cgml, cdec, cdec.type);
-                  
-                  if (!model.typed && getNeedTyped(propType)) 
-                  {
-                    throw Cgml.errorLine(dec) +
-                      "Can't use \"t\" instade solid model";
-                  }
-                  
-                  var prop = new Prop(
-                    cdec.name,
-                    propType,
-                    (cdec.key == OptionProp));
-                    
-                  prop._cgmlDec = cdec;
-                  model.properties.add(prop);
-                }
-                  
-              }
-              case Variant(variant):
-              {
-                if (getTypeByCgmlDec(cgml, dec, dec.type) != Void)
-                  throw Cgml.errorLine(dec) + "Variant can't extends types";
-
-                var props = variant.properties;
-                for (cdec in dec.children)
-                {
-                  if (cdec.key == OptionProp)
-                  {
-                    throw Cgml.errorLine(dec) +
-                      "Variant can't containt optional fields";
-                  }
-
-                  var propType = getTypeByCgmlDec(cgml, cdec, cdec.type);
-                  
-                  if (!variant.typed && getNeedTyped(propType)) 
-                  {
-                    throw Cgml.errorLine(dec) +
-                      "Can't use \"t\" instade solid variant";
-                  }
-                    
-                  props.add(new Prop(cdec.name, propType));
-                }
-                  
-                variant.annotations = preprocessAnnotations(dec.annotations, defines);
-              }
-              default:
-              {
-              }
-            }
-          }
-        }
-      }
-    }
-
-    // Copy virtual generics
-    for (ttt in vgTypes)
-        fillVirtualGeneric(ttt.t3, ttt.t1, ttt.t2, ttt.ns);
-    
-    // Теперь посмотрим не сдублировали ли мы где нибудь свойства.
-    for (node in types)
-    {
-      var properties:FastList<Prop> = null;
-      var parentProps:FastList<Prop> = null;
-      
-      switch (getNodeType(node))
-      {
-        case Model(m):
-        {
-          parentProps = getNodeProperties(m.type);
-          properties = m.properties;
-        }
-        case Variant(v):
-        {
-          properties = v.properties;
-        }
-        default: {}
-      }
-      
-      if (properties != null)
-      {
-        for (p in properties)
-        {
-          if (getPropCount(p.name, properties) > 1)
-          {
-            throw Cgml.errorLine(p._cgmlDec)+
-              "Duplicate declatation of field " + p.name;
-          }
-          
-          if (parentProps != null)    
-          {
-            if (getPropCount(p.name, parentProps) > 0)
-            {
-              throw Cgml.errorLine(p._cgmlDec)+
-                "Declatation " + p.name + " was declared in parent model";
-            }
-          }  
-        }
-      }
-    }
-  }
-
-  function preprocessAnnotations(rawAnnotations:List<String>, defines:List<String>)
-  {
-    var r = new List<String>();
-    for (a in rawAnnotations) {
-      var s = a.split(":");
-      if (s.length > 1)
-      {
-        if (Lambda.has(defines, s[0]))
-          r.add(s[1]);
-      }
-      else r.add(a);
-    }
-    return r;
-  }
-  function setType(n:Node)
-  {
-    var name = getNodeTrueName(n);
-    var ns = getNodeNs(n);
-          
-    types.set(getTypenameForNs(ns, name), n);
-
-    var tbns = typesByNs.get(ns);
-    if (tbns == null)
-    {
-      tbns = new List<Node>();
-      typesByNs.set(ns, tbns);
-    }
-    
-    tbns.add(n);
-  }
-  
-  function getType(ns:String, name:String)
-  {
-    return types.get(getTypenameForNs(ns, name));
-  }
-  
-  public static function compareAnnotations(a:Node, b:Node):Bool
-  {
-    var aAnnotations = getNodeAnnotations(a);
-    var bAnnotations = getNodeAnnotations(b);
-    
-    if (aAnnotations == null && bAnnotations == null)
-      return true;
-    for (an in aAnnotations)
-      if (!Lambda.has(bAnnotations, an))
-        return false;
-
-    for (bn in bAnnotations)
-      if (!Lambda.has(aAnnotations, bn))
-        return false;
-    
-    return true;
-  }
-  
-  public static function getNodeAnnotations(a:Node):List<String>
-  {
-    return switch (a)
-    {
-      case Model(v): v.annotations;
-      case Variant(v): v.annotations;
-      default: null;
-    };
-  }
-  
-  function getPropCount(name:String, properties:FastList<Prop>):Int
-  {
-    var count = 0;
-    
-    for (p in properties)
-    {
-      if (p.name == name)
-        count++;        
-    }
-    
-    return count;
-  }
-  
-  function getTypeByCgmlDec(cgml:Cgml, dec:CgmlDec, dectype:DecType):Node
-  {
-    if (dectype.of == null)
-    {
-      var type = findType(cgml.ns, dectype.name);
-      
-      if (type == null) 
-        throw Cgml.errorLine(dec) + "Unknown type '" + dectype.name + "'";
-
-      return type;
-    }
-    else
-    {
-      var type2 = getTypeByCgmlDec(cgml, dec, dectype.of);//findType(cgml.ns, parts[1]);
-      switch (dectype.name)
-      {
-        // Check. May be it is list.
-        case "blist", "slist", "ilist":
-        {
-          if (type2 == null) 
-            throw Cgml.errorLine(dec) + "Unknown type " + dectype.of.name;
-          
-          try
-          {
-            return List(getListSize(dectype.name), type2);
-          }
-          catch (e:String)
-          {
-            throw Cgml.errorLine(dec) + e;
-          }
-        }
-        default:
-        {
-          var type1 = findType(cgml.ns, dectype.name);
-
-          if (type1 == null) 
-            throw Cgml.errorLine(dec) + "Unknown type " + dectype.name;
-
-          if (!getNodeTyped(type1))
-          {
-            throw Cgml.errorLine(dec) + 
-              "Solid models can't use type parameters " + dectype.name;
-          }
-
-          if (type2 == null) 
-            throw Cgml.errorLine(dec) + "Unknown type " + dectype.of.name;
-
-          if (getNodeTyped(type2))
-          {
-            throw Cgml.errorLine(dec) + 
-              "Incorrent type parameter " + dectype.name + " for " + dectype.of.name;
-          }
-    
-          if (type2 == T || getNodeTyped(type2))
-            return type1;
-
-          var type3 = getVirtualGeneric(type1, type2, cgml.ns);
-
-          vgTypes.set(
-            getTypenameForNs(cgml.ns, getNodeTrueName(type3)), 
-            {t1:type1, t2: type2, t3:type3, ns:cgml.ns}
-          );
-
-          return type3;
-        }
-      }
-    }
-  }
-  
-  function getVirtualGeneric(type1:Node, type2:Node, ns:String) 
-  {
-    var vgName = getNodeTrueName(type1) + "-of-" + getNodeTrueName(type2);
-    var type3 = findType(ns, vgName);
-    
-    if (type3 == null)
-    {
-      type3 = switch (type1)
-      {
-        case Model(v): Model(new Model(vgName, ns, false, false));
-        case Variant(v): Variant(new Variant(vgName, ns, false));
-        case T, Void, List(_,_): throw "Internal error";
-      }
-      
-      setType(type3);
-    }
-    
-    return type3;
-  }
-  
-  function fillVirtualGeneric(vg:Node, type1, type2, ns)
-  {
-    var uid = switch (vg) {
-      case Model(v): v.uid;
-      case Variant(v): v.uid;
-      case T, Void, List(_,_): -1;
-    }
-    
-    if (vgFilled.get(uid))
-      return;
-    else vgFilled.set(uid, true);
-
-    var targetProps = getNodeProperties(vg);
-    
-    if (getNodeTyped(type2))
-      throw "Internal error: unparametrized virtual generic.";
-    
-    for (prop in getNodeProperties(type1))
-    {
-      var p = prop.clone();
-      
-      switch (p.type)
-      {
-        case T: p.type = type2;
-        case List(s,v):
-        {
-          if (getNodeTyped(v))
-          {
-            var pvg = getVirtualGeneric(v, type2, ns);
-            fillVirtualGeneric(pvg, v, type2, ns);
-            p.type = List(s,pvg);
-          }
-        }
-        case Model(_), Variant(_):
-        {
-          if (getNodeTyped(p.type))
-          {
-            var pvg = getVirtualGeneric(p.type, type2, ns);
-            fillVirtualGeneric(pvg, p.type, type2, ns);
-            p.type = pvg;
-          }
-        }
-        case Void:throw "Internal error";
-      }
-      
-      targetProps.add(p);
-    }
-    
-    switch (vg) 
-    {
-      case Model(v):
-      {
-        var parentType = getNodeType(type1);
-        if (getNodeTyped(parentType))
-        {
-          var pvg = getVirtualGeneric(parentType, type2, ns);
-          fillVirtualGeneric(pvg, parentType, type2, ns);
-          parentType = pvg;
-        }  
-        
-        v.type = parentType;
-        v.annotations = getNodeAnnotations(type1);
-      } 
-      case Variant(v): v.annotations = getNodeAnnotations(type1);
-      case T, Void, List(_,_): throw "Internal error";
-    }    
-  }
-  
-  public static function getListSize(trueName:String):ListSize
-  {
-    return switch (trueName.charAt(0))
-    {
-      case "b": Small;
-      case "s": Medium;
-      case "l": Big;
-      default: throw "Invalid list size modificator";
-    };
-  }
-
-  function findType(ns:String, name:String):Node
-  {
-    switch (name)
-    {
-      case "void": return Void;
-      case "t": return T;
-      default: {};
-    }
-      
-    var type = types.get(getTypenameForNs(ns, name));
-    
-    if (type == null)
-    {
-      if (uses.get(ns) != null) for (n in uses.get(ns))
-      {
-        type = types.get(getTypenameForNs(n, name));
-        
-        if (type != null)
-          break;
-      }
-    }
-    
-    return type;
-  }
-  
-  public static function getNodeModel(node:Node):Model
-  {
-    return switch (node)
-    {
-      case Model(v): v;
-      default: null;
-    };
-  }
-  
-  public static function getNodeType(node:Node):Node
-  {
-    return switch (node)
-    {
-      case Model(v): v.type;
-      case Variant(v): Void;
-      case List(_, v): getNodeType(v);
-      default: Void;
-    };
-  }
-  
-  public static function getNodeTyped(node:Node):Bool
-  {
-    return switch (node)
-    {
-      case Model(v): v.typed;
-      case Variant(v): v.typed;
-      case List(_,_): true;
-      default: false;
-    };
-  }
-
-  public static function getNeedTyped(node:Node):Bool
-  {
-    return switch (node)
-    {
-      case T: true;
-      default: false;
-    };
-  }
-
-  public static function getNodeProperties(node:Node):FastList<Prop>
-  {
-    return switch (node)
-    {
-      case Model(v): v.properties;
-      case Variant(v): v.properties;
-      default: null;
-    };
-  }
-
-  public static function getNodeFullProperties(node:Node):Iterable<Prop>
-  {
-    return switch (node)
-    {
-      case Model(v): v.getFullProperties();
-      case Variant(v): Lambda.array(v.properties);
-      default: null;
-    };
-  }
-
-  public static function extractTypes(node:Node):List<Node>
-  {
-    var types = new List<Node>();
-    switch (node)
-    {
-      case Model(v): {
-        for (p in v.properties)
-          if (!Lambda.has(types, p.type)) 
-            types.add(p.type);
-      }
-      case Variant(v): {
-        for (p in v.properties)
-          if (!Lambda.has(types, p.type)) 
-            types.add(p.type);
-      }
-      default: {};
-    }
-    return types;
-  }
-
-  public static function getNodeTrueName(node:Node):String
-  {
-    return switch (node) 
-    {
-      case Model(v): v.name;
-      case Variant(v): v.name;
-      case T: "t";
-      case List(s, v):
-      {
-        var ltn = switch (s)
-        {
-          case Small: "b";
-          case Medium: "s";
-          case Big: "i";
-        } 
-        
-        ltn + "list." + getNodeTrueName(v);
-      }
-      case Void: "void";
-    };
-  }
-
-  /**
-   *  Если узел - модель, то возвращаем ее пространство имен.
-   */
-  public static function getNodeNs(node:Node):String
-  {
-    return switch (node)
-    {
-      case Model(v): v.ns;
-      case Variant(v): v.ns;
-      case List(_, v): getNodeNs(v);
-      case T, Void: null;  
-    };
-  }
-    
-  public static function getNodeIsList(node:Node)
-  {
-    return switch (node)
-    {
-      case List(_,_): true;
-      case Model(_), Variant(_), T, Void: false;
-    };
-  }
-  
-  inline public function getTypenameForNs(ns:String, name:String)
-  {
-    return ns + "." + name;
-  }
-}
-
-enum Node
-{
-  Model      (type:Model);
-  Variant    (type:Variant); 
-  List       (size:ListSize, of:Node);
-  Void;
-  T;
-}
-
-enum ListSize
-{
-  Small;  // b
-  Medium; // s
-  Big;
-}
-
-/**
- *  Вариант. Что-то вроде перечисления. Можно использовать в качестве
- *  полиморфорфного типа. 
- */
-class Variant
-{
-  public var ns:String;
-  public var properties:FastList<Prop>;
-  public var name:String;
-  public var typed:Bool;
-  public var annotations:List<String>;
-
-  public var uid(default, null):Int;
-  
-  public function new(name, ns, typed)
-  {
-    uid = BaseType.__lastUid++;
-    
-    this.ns = ns;
-    this.name = name;
-    this.typed = typed;
-    this.properties = new FastList<Prop>();
-  }
-}
-
-/**
- */
-class Prop extends BaseType 
-{
-  public var _cgmlDec:CgmlDec;
-  
-  public var option:Bool;
-  
-  public function new(name, type, ?option=false)
-  {
-    super(name, type);
-    this.option = option;
-  }
-
-  public function clone()
-  {
-    return new Prop(name, type, option);
-  }
-}
-
-/**
- *  Модель. Описывает класс модели с её свойствами.
- */
-class Model extends BaseType
-{
-  public var ns:String;
-  public var properties:FastList<Prop>;
-  public var annotations:List<String>;
-  
-  public var final:Bool;
-  public var typed:Bool;
-  
-  public function new(name, ns, final, typed)
-  {
-    super(name, null);
-    
-    this.ns = ns;
-    this.final = final;
-    this.typed = typed;
-    this.properties = new FastList<Prop>();
-  }
-
-  /**
-   *  Returns all of the properties include parent type.
-   */
-  public function getFullProperties(selfownPropertiesInBegin=false):Array<Prop>
-  {
-    var result = new Array<Prop>();
-
-    if (selfownPropertiesInBegin)
-      for (p in properties)
-        result.push(p);
-
-    if (type != null)
-    {
-      var extnds = Ast.getNodeModel(type);
-
-      if (extnds != null)
-        result = result.concat(extnds.getFullProperties());
-    }
-
-    if (!selfownPropertiesInBegin)
-      for (p in properties)
-        result.push(p);
-
-    return result;
-  }
-  
-  public function hasProperty(name:String, type:Node)
-  {
-    for (p in properties)
-      if (p.name == name && p.type == type)
-        return true;
-    
-    if (this.type != Void)
-      return Ast.getNodeModel(this.type).hasProperty(name, type);
-      
-    return false;
-  }
-  
-  public function hasPropertyUnsafe(name:String, type:String)
-  {
-    for (p in properties)
-      if (p.name == name && Ast.getNodeTrueName(p.type) == type)
-        return true;
-    
-    if (this.type != Void)
-      return Ast.getNodeModel(this.type).hasPropertyUnsafe(name, type);
-      
-    return false;
-  }
-}
-
-/**
- *  Базовый тип.
- */
-class BaseType
-{
-
-//--- Открытые свойства --------------------------------------------------------
-
-  //--- type -------------------------------------------------------------------
-
-  public var type:Node;
-
-  //--- name -------------------------------------------------------------------
-
-  /**
-   *  Имя. Можно использовать латинские буквы и знак "-". Обратите внимание,
-   *  что в сгенерированном коде имя может отличаться в зависимости от языка.
-   */
-  public var name:String;
-
-  public var uid(default, null):Int;
-  public static var __lastUid:Int = 0;
-  
-//--- Открытые методы ----------------------------------------------------------
-
-  /**
-   *  Конструктор
-   */
-  public function new(name, type)
-  {
-    uid = __lastUid++;
-    
-    this.name = name;
-    this.type = type;
-  }
-}

src/com/yarrcad/cg/Cgml.hx

-/*
- * This file is part of the CGML Compiler
- *
- * Copyright(c) 2005-2010 Aleksey Fomkin <aleksey.fomkin@gmail.com>
- * http://bitbucket.org/yelbota/cgml-compiler
- *
- * This file may be licensed under the terms of of the
- * GNU General Public License Version 3 (the ``GPL'').
- *
- * Software distributed under the License is distributed
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
- * express or implied. See the GPL for the specific language
- * governing rights and limitations.
- *
- * You should have received a copy of the GPL along with this
- * program. If not, go to http://www.gnu.org/licenses/gpl.html
- * or write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-package com.yarrcad.cg;
-
-import haxe.FastList;
-
-import haxe.io.Input;
-import haxe.io.Eof;
-
-/**
- *  Разборщик CGML-файлов на синтаксические узлы.
- *  @author aleksey.fomkin@gmial.com
- */
-class Cgml
-{
-
-//--- Скрытые переменные класса ------------------------------------------------
-
-  static var KEY_NS            = "%".charCodeAt(0);
-  static var KEY_COMMENT       = "#".charCodeAt(0);
-  static var KEY_VARIANT       = "*".charCodeAt(0);
-  static var KEY_TYPED_VARIANT = "$".charCodeAt(0);
-  static var KEY_MODEL         = "!".charCodeAt(0);
-  static var KEY_FINALMODEL    = ".".charCodeAt(0);
-  static var KEY_TYPEDMODEL    = "^".charCodeAt(0);
-  static var KEY_SOLID_PROP    = "@".charCodeAt(0);
-  static var KEY_OPTION_PROP   = "?".charCodeAt(0);
-  static var KEY_ANNOTATION    = ">".charCodeAt(0);
-
-  static var KEY_SPACE = " ".charCodeAt(0);
-  static var KEY_TAB = "\t".charCodeAt(0);
-
-//--- Открытые переменные ------------------------------------------------------
-
-  /**
-   *  Список синтаксический узлов
-   */
-  public var nodes:FastList<CgmlNode>;
-
-  public var ns(default, null):String;
-  
-  public var filename(default, null):String;
-  
-//--- Открытые методы ----------------------------------------------------------
-  
-  /**
-   *  Конструктор
-   *  @param Сам ввод
-   *  @param Имя файла, если таковое есть
-   */
-  public function new(input, ns, ?filename=null)
-  {
-    this.ns = ns;
-    this.filename = filename;
-    this.nodes = new FastList<CgmlNode>();
-    
-    short_lex(input, filename);
-  }
-
-//--- Скрытые методы -----------------------------------------------------------
-  
-  /**
-   *  Разобрать ввод на синтаксические узлы.
-   *  @param Сам ввод
-   *  @param Имя файла, если таковое есть
-   */
-  function short_lex(input:Input, ?filename="")
-  {
-    var linenum = 0;
-
-    var currentDec:CgmlDec = null;
-    var currentAnnotations:List<String> = new List();
-    
-    while (true)
-    {
-      var line:String = null;
-      
-      try
-      {
-        line = StringTools.rtrim(input.readLine()); 
-      }
-      catch (error:Eof)
-      {
-          break;
-      }
-
-      linenum++;
-        
-      if (line.length == 0)
-      {
-        continue; 
-      }
-      else
-      {
-        var node = short_parseLine(line);
-
-        if (node == null)
-          continue;
-        
-        switch (node)
-        {
-          case Declaration(dec):
-          {
-            dec.filename = filename;
-            dec.linenum = linenum;
-            dec.annotations = currentAnnotations;
-            
-            currentAnnotations = new List();
-            
-            if (dec.name == null || dec.type.name == null)
-              throw errorLine(dec) + "Every declaration must contain key, type and name.";
-
-            if (dec.key == Unknown)
-              throw errorLine(dec) + "Unknown declaration key.";
-            
-            if (dec.isChild)
-            {
-              if (currentDec == null)
-                throw errorLine(dec) + "Children declaration (wich have indentation) without parent.";
-              else
-              {
-                if (dec.key != SolidProp && dec.key != OptionProp)
-                  throw errorLine(dec) + "Invalid declaration key for second level declaration.";
-              
-                currentDec.children.add(dec);
-              }
-            }
-            else
-            {
-              if (dec.key == SolidProp || dec.key == OptionProp)
-                throw errorLine(dec) + "Invalid declaration key for top level declaration.";
-
-              currentDec = dec;
-              nodes.add(node);
-            }
-          }
-          case Namespace(ns):
-          {
-            nodes.add(node);
-          }
-          case Annotation(an):
-          {
-            currentAnnotations.add(an);
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   *  Обработать строку, как синтаксический узел.
-   *  @param Сама строка
-   *  @param Является ли узел дочерним.
-   */  
-  function short_parseLine(line:String, ?child=false)
-  {
-    var frst = line.charCodeAt(0);
-
-    if (frst == KEY_SPACE || frst == KEY_TAB)
-    {
-      return short_parseLine(StringTools.ltrim(line), true);
-    }
-    else if (frst == KEY_COMMENT)
-    {
-      // пока с комментариями ничего не делаем
-      return null;
-    }
-    else
-    {
-      // Отчистим все, что слева, и заменим табы на пробелы.
-      line = StringTools.replace(line, "\t", " ");
-      line = StringTools.ltrim(line);
-      
-      // Уберем двойные пробелы
-      while (line.indexOf("  ") > 0)
-        line = StringTools.replace(line, "  ", " ");
-      
-      var node:CgmlNode = null;
-      var parts = line.split(" ");
-      
-      if (frst == KEY_NS)
-      {
-        node = Namespace(parts[1]);  
-      }
-      else if (frst == KEY_ANNOTATION)
-      {
-        node = Annotation(parts[1]);  
-      }
-      else
-      {
-        var key:CgmlKey = switch (frst)
-        {
-          case KEY_VARIANT: Variant;
-          case KEY_MODEL: Model;
-          case KEY_FINALMODEL: FinalModel;
-          case KEY_TYPEDMODEL: TypedModel;
-          case KEY_SOLID_PROP: SolidProp;
-          case KEY_OPTION_PROP: OptionProp;
-          case KEY_TYPED_VARIANT: TypedVariant;
-
-          default: Unknown;
-        }
-        
-        node = Declaration(new CgmlDec(key, parts[1], parts[2], child));  
-      }
-        
-      return node;
-    }
-  }
-
-  /**
-   *  Получить заголовок для ошибки.
-   */
-  public static inline function errorLine(dec:CgmlDec)
-  {
-    return dec.filename + "(" + Std.string(dec.linenum) + "): ";
-  }
-}
-
-/**
- *  Ключ синтаксического узла
- *  @author aleksey.fomkin@gmial.com
- */
-enum CgmlKey
-{
-  Variant;
-  TypedVariant;
-  Model;
-  FinalModel;
-  TypedModel;
-  SolidProp;
-  OptionProp;
-  Unknown;
-}
-
-/**
- *  Тип синтаксического узла
- *  @author aleksey.fomkin@gmial.com
- */
-enum CgmlNode
-{
-  Declaration(dec:CgmlDec);
-  Annotation(dec:String);
-  Namespace(ns:String);    
-}
-
-class DecType 
-{
-  public var name:String;
-  public var of:DecType;
-  
-  public function new(?name:String="", ?of:DecType=null)
-  {
-    this.name = name;
-    this.of = of;
-  }
-}
-
-/**
- *  Декларация
- *  @author aleksey.fomkin@gmial.com
- */
-class CgmlDec
-{
-  inline public static var validChars = "qwertyuiopasdfghjklzxcvbnm-1234567890:";
-  
-  public var key:CgmlKey;
-  public var type:DecType;
-  public var annotations:List<String>;
-  public var name:String;
-  public var isChild:Bool;
-  public var children(default, null):FastList<CgmlDec>;
-  
-  public var filename:String;
-  public var linenum:Int;
- 
-  /**
-   *  Конструктор
-   */ 
-  public function new(key, typeName:String, name, isChild)
-  {
-    this.key = key;
-     this.name = name;
-
-    var dec = type = new DecType();      
-    for (i in 0 ... typeName.length)
-    {
-      var c = typeName.charAt(i);
-      switch (c)
-      {
-        case ".":
-        {
-          for (c in dec.name.split(""))
-            if (validChars.indexOf(c) < 0)
-              throw Cgml.errorLine(this) + "Illegal character '"+c+"'.";
-
-          dec.of = new DecType();
-          dec = dec.of;
-        }
-        default: dec.name += c;
-      }
-    }
-    
-    for (c in dec.name.split(""))
-      if (validChars.indexOf(c) < 0)
-        throw Cgml.errorLine(this) + "Illegal character '"+c+"'.";
-    
-    this.isChild = isChild;
-    this.children = new FastList<CgmlDec>();
-  }
- 
-  /**
-   *  Представляет объект в виде строки
-   */ 
-  public function toString()
-  {
-    var skey = switch (key)
-    {
-      case Variant: "Variant";
-      case TypedVariant: "TypedVariant";
-      case Model: "Model";
-      case FinalModel: "Model";
-      case TypedModel: "TypedModel";
-      case SolidProp: "SolidProp";
-      case OptionProp: "OptionProp";
-      case Unknown: "_";
-    }
-    
-    var s = skey + " " + name + ":" + type + "\n";
-    
-    for (c in children)
-      s += "\t" + c;
-      
-    return s;
-  }
-  
-  public function getSourceModifyDate():Date
-  {
-    return sys.FileSystem.stat(filename).mtime;
-  }
-}

src/com/yarrcad/cg/CodeGenerator.hx

-/*
- * This file is part of the CGML Compiler
- *
- * Copyright(c) 2010 Aleksey Fomkin <aleksey.fomkin@gmail.com>
- * http://bitbucket.org/yelbota/cgml-compiler
- *
- * This file may be licensed under the terms of of the
- * GNU General Public License Version 3 (the ``GPL'').
- *
- * Software distributed under the License is distributed
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
- * express or implied. See the GPL for the specific language
- * governing rights and limitations.
- *
- * You should have received a copy of the GPL along with this
- * program. If not, go to http://www.gnu.org/licenses/gpl.html
- * or write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-package com.yarrcad.cg;
-
-import com.yarrcad.cg.writers.AbstractWriter;
-import com.yarrcad.cg.util.FileDateMark;
-import com.yarrcad.cg.util.AbstractDateMark;
-
-import haxe.FastList;
-
-//import com.yarrcad.cg.writers.ScalaWriter;
-import com.yarrcad.cg.writers.HaxeWriter;
-import com.yarrcad.cg.writers.JavaWriter;
-import com.yarrcad.cg.writers.AS3Writer;
-
-import com.yarrcad.cg.util.DirectoryDateMark;
-
-import com.yarrcad.cg.Ast;
-import com.yarrcad.cg.Cgml;
-
-import haxe.io.StringInput;
-
-import sys.FileSystem;
-import sys.io.File;
-
-using Lambda;
-using StringTools;
-
-class CodeGenerator
-{
-  static function main()
-  {
-    var argAct:ArgAct = Continue;
-    var sourceDirectory = null;
-    
-    var targets = new List<Target>();
-    
-    var addPrefix:String = null;
-    var addWarn = false;
-    var yarrnetInterface = false;
-    var javaUseDouble = false;
-    var defines = new List<String>();
-    
-    var args = Sys.args();
-    
-    if (args.length == 0)
-    {
-      Sys.print("Usage:"
-        + "\n -source  Use the cgml source directory."
-        + "\n"
-        + "\n -haxe    Directory for generated haXe modules."
-//        + "\n -scala   Directory for generated haXe modules."
-        + "\n -java    Directory for generated Java classes."
-        + "\n -as3     Directory for generated ActionScript3 classes."
-        + "\n"
-        + "\n --model-prefix       Add prefix to model."
-        + "\n --java-use-double    Use java.lang.double for float values."
-        + "\n --define, -D         Define condition for annotations."
-        + "\n");
-        
-      Sys.exit(0);
-    }
-    
-    for (arg in args)
-    {
-      switch (argAct)
-      {
-        case Source:
-        {
-          if (FileSystem.exists(arg) && FileSystem.isDirectory(arg))
-            sourceDirectory = FileSystem.fullPath(arg);
-          else makeError("Defined source directory not found.");
-          
-          argAct = Continue;
-        }
-        case Haxe:
-        {
-          if (FileSystem.exists(arg) && FileSystem.isDirectory(arg))
-            targets.add(Target.Haxe(FileSystem.fullPath(arg)));
-          else 
-            makeError("Defined haXe output directory not found.");
-
-          argAct = Continue;
-        }
-        case Java:
-        {
-          if (FileSystem.exists(arg) && FileSystem.isDirectory(arg))
-            targets.add(Target.Java(FileSystem.fullPath(arg)));
-          else 
-            makeError("Defined java output directory not found.");
-
-          argAct = Continue;
-        }
-/*        case Scala:
-        {
-          if (FileSystem.exists(arg) && FileSystem.isDirectory(arg))
-            targets.add(Target.Scala(FileSystem.fullPath(arg)));
-          else 
-            makeError("Defined scala output directory not found.");
-
-          argAct = Continue;
-        }*/
-        case As3:
-        {
-          if (FileSystem.exists(arg) && FileSystem.isDirectory(arg))
-            targets.add(Target.As3(FileSystem.fullPath(arg)));
-          else 
-            makeError("Defined Actionscript3 output directory not found.");
-
-          argAct = Continue;
-        }
-        case HaxePrefix:
-        {
-          addPrefix = arg;
-          argAct = Continue;
-        }
-        case Define:
-        {
-          defines.add(arg);
-          argAct = Continue;
-        }
-        case Continue: argAct = switch (arg)
-        {
-          case "-source": Source;
-          case "-haxe": Haxe;
-//          case "-scala": Scala;
-          case "-java": Java;
-          case "-as3": As3;
-          case "--generate-warnings":
-          {
-            addWarn = true;
-            Continue;
-          }
-          case "--yarrnet-interface":
-          {
-            yarrnetInterface = true;
-            Continue;
-          }
-          case "--model-prefix": HaxePrefix;
-          case "--define", "-D": Define;
-          case "--java-use-double":
-          {
-            javaUseDouble = true;
-            argAct = Continue;
-          }
-          default: Continue; 
-        }
-      }
-    }
-
-    if (sourceDirectory == null)
-      makeError("Source directory doesn't defined.");
-    
-    // Prepare targets writers.
-    var writers = targets.map( function(target)
-    {
-      var w:AbstractWriter;
-      switch (target)
-      {
-        case Haxe(s): w = new HaxeWriter(s, new FileDateMark(s, sourceDirectory));
-//        case Scala(s): w = new ScalaWriter(s, new FileDateMark(s, sourceDirectory)); 
-        case As3(s): w = new AS3Writer(s, new DirectoryDateMark(s, sourceDirectory)); 
-        case Java(s): w = new JavaWriter(s, new DirectoryDateMark(s, sourceDirectory), javaUseDouble); 
-      }
-      return w;
-    });
-    
-    // Look, may be all generated modules is up to date.  
-    var allreadyGenerated = true;
-    for (module in getModulesFromSourceDirectory(sourceDirectory))
-    {
-      var ns = pathToNs(module);
-
-      for (w in writers)
-        if (w.dateMark.getGenerationRequired(ns))
-          allreadyGenerated = false;
-    }
-    
-    // Nothing to do. All targets is up to date.
-    if (allreadyGenerated)
-      Sys.exit(0);
-    
-    // Ok. We need to generate something. At firts we 
-    // Make cgml-token tree from modules in source directory.
-    var cgmls = getCgmlsFromDirectory(sourceDirectory);
-
-    // Add basic language cgml from resource
-    cgmls.push(new Cgml(
-      new haxe.io.StringInput(
-        haxe.Resource.getString("basic")), 
-          "cgml.lang.basic", "lang.basic.cgml"
-    ));
-
-    // Add structures cgml from resources
-    cgmls.push(new Cgml(
-      new haxe.io.StringInput(
-        haxe.Resource.getString("struct")), 
-          "cgml.lang.struct", "lang.struct.cgml"
-    ));
-
-    // Create abstract syntax tree from cgml-tokens 
-    var ast = try { new Ast(cgmls, defines); } 
-      catch (error:String) { makeError(error); null; }
-    
-    // Generate code for target list.
-    // Inside targets we will check date make once again.
-    for (writer in writers)
-       writer.write(ast, addWarn, yarrnetInterface, addPrefix);
-  }
-  
-  /**
-   *  Convet relative path of module to namespace.
-   *  @param path Something lile "com/company/project/module.cgml"
-   *  @return Something like "com.company.project.module"
-   */
-  static function pathToNs(path:String)
-  {
-    if (path.endsWith(".cgml")) path = path.substr(0, path.length-5);
-    return path.split("/").filter(function(s) return (s != "")).join(".");
-  }
-
-  /**
-   *  Returns relative paths for the modules.
-   *  @param absolutePath Something like "/home/useranme/projects/projectname/cgml_sources"
-   *  @return List of modules paths.
-   */
-  static function getModulesFromSourceDirectory(absolutePath:String, relativePath:String="") 
-  {
-    var result = new Array<String>();
-    for (file in FileSystem.readDirectory(absolutePath))
-    {
-      var nAbsolutePath = absolutePath + "/" + file;
-      var nRelativePath = relativePath + "/" + file;
-      if (FileSystem.isDirectory(nAbsolutePath))
-        result = result.concat(getModulesFromSourceDirectory(nAbsolutePath, nRelativePath));
-      else if (file.endsWith(".cgml")) result.push(nRelativePath);
-    }
-    
-    return result;
-  }
-
-  /**
-   *  Parse source directory and create list with cgml-tokens.
-   *  @param absolutePath Something like "/home/useranme/projects/projectname/cgml_sources"
-   *  @return List of cgml-tokens
-   */
-  static function getCgmlsFromDirectory(absolutePath:String, relativePath:String = "")
-  {
-    var result = new Array<Cgml>();
-    for (file in FileSystem.readDirectory(absolutePath))
-    {
-      var nAbsolutePath = absolutePath + "/" + file;
-      var nRelativePath = relativePath + "/" + file;
-      
-      if (FileSystem.isDirectory(nAbsolutePath))
-      {
-        // Resursive search.
-        result = result.concat(getCgmlsFromDirectory(nAbsolutePath, nRelativePath));
-      }
-      else
-      {
-        // Parse cgml modules and ignore anothers.
-        if (file.endsWith(".cgml"))
-          result.push(getCgmlFromFile(nRelativePath, nAbsolutePath));
-      }
-    }
-    
-    return result;
-  }
-  
-  /**
-   *  Takes module and make cgml-tokens.
-   *  @param absolutePath Something like
-   *   "/home/useranme/projects/projectname/cgml_sources/com/company/proj/module.cgml"
-   *  @param relativePath Something like "com/company/proj/module.cgml"
-   *  @return List of cgml-tokens
-   */
-  static function getCgmlFromFile(relativePath:String, absolutePath:String)
-  {
-    return try
-    {
-      new Cgml(File.read(absolutePath, false),
-        pathToNs(relativePath), absolutePath);
-    }
-    catch (error:String)
-    {
-      makeError(error);
-      null;
-    }
-  }
-  
-  static function makeError(error)
-  {
-    Sys.stderr().writeString(error + "\n");
-    Sys.exit(2);
-  }
-}
-
-/**
- *  CLI agruments parsing actions.
- */
-enum ArgAct
-{
-  Haxe;
-  Java;
-  As3;
-//  Scala;
-
-  Source;
-  HaxePrefix;
-  Continue;
-  Define;
-}
-
-/**
- *  Compilation target.
- */
-enum Target
-{
-  Haxe(path:String);
-  As3(path:String);
-  Java(path:String);
-//  Scala(path:String);
-}

src/com/yarrcad/cg/util/AbstractDateMark.hx

-/*
- * This file is part of the CGML Compiler
- *
- * Copyright(c) 2010 Aleksey Fomkin <aleksey.fomkin@gmail.com>
- * http://bitbucket.org/yelbota/cgml-compiler
- *
- * This file may be licensed under the terms of of the
- * GNU General Public License Version 3 (the ``GPL'').
- *
- * Software distributed under the License is distributed
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
- * express or implied. See the GPL for the specific language
- * governing rights and limitations.
- *
- * You should have received a copy of the GPL along with this
- * program. If not, go to http://www.gnu.org/licenses/gpl.html
- * or write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-package com.yarrcad.cg.util;
-import sys.FileSystem;
-
-import sys.io.File;
-
-class AbstractDateMark 
-{
-  //---------------------------------------------------------------------------
-  //
-  //  Private declarations
-  //
-  //---------------------------------------------------------------------------
-  
-  /**
-   *  Hashset with namespaces whose mark was overriden.
-   */
-  private var updatedNamespaces:Hash<Bool>;
-  
-  private var sourceMDatesCache:Hash<Date>;
-  
-  /**
-   *  Abstract constructor.
-   */
-  private function new(generatedRoot:String, sourceRoot:String)
-  {
-    updatedNamespaces = new Hash();
-    sourceMDatesCache = new Hash();
-    
-    this.generatedRoot = generatedRoot;
-    this.sourceRoot = sourceRoot;
-  }
-
-  /**
-   *  Returns true if modification date was updated.
-   */  
-  private function getUpdated(ns:String):Bool
-  {
-    return updatedNamespaces.get(ns);
-  }
-
-  /**
-   *  Returns source module modification date.
-   */
-  private function getSourceMTime(ns:String):Date
-  {
-    var date = sourceMDatesCache.get(ns);
-
-    if (date == null)
-    {
-      var module = sourceRoot + "/" + 
-        ns.split(".").join("/") + ".cgml";
-
-      date = FileSystem.exists(module)
-        ? FileSystem.stat(module).mtime
-        : Date.fromTime(0);
-        
-      sourceMDatesCache.set(ns, date);  
-    }
-    
-    return date;
-  }
-  
-  //---------------------------------------------------------------------------
-  //
-  //  Abstract methods
-  //
-  //---------------------------------------------------------------------------
-
-  /**
-   *  Get date of the genrated file.
-   */
-  private function getDate(ns:String):Date
-  {
-    // Abstract
-    return null;
-  }
-  
-  /**
-   *  Set date to generated file.
-   */
-  private function setDate(ns:String, date:Date)
-  {
-    // Abstract
-  }
-
-  //---------------------------------------------------------------------------
-  //
-  //  Public properties
-  //
-  //---------------------------------------------------------------------------
-
-  /**
-   *  Sources of directory with generated files.
-   */  
-  public var generatedRoot(default, null):String;
-
-  /**
-   *  Cgml modules source directory.
-   */
-  public var sourceRoot(default, null):String;
-  
-  //---------------------------------------------------------------------------
-  //
-  //  Public methods
-  //
-  //---------------------------------------------------------------------------
-  
-  /**
-   *  @param date Modification of the generated file.
-   */
-  public function getGenerationRequired(ns:String):Bool
-  {
-    /*trace("getGenerationRequired:");
-    trace(" ns: " + ns);
-    trace(" sources mtime: " + getSourceMTime(ns).toString());
-    trace(" generated mtime: " + getDate(ns).toString());
-    trace("");*/
-    
-    return (getUpdated(ns) || 
-      (getDate(ns).toString() != getSourceMTime(ns).toString()));
-  }
-  
-  public function updateMark(ns:String)
-  {
-    if (!getUpdated(ns))
-    {
-      setDate(ns, getSourceMTime(ns));
-      updatedNamespaces.set(ns, true);
-    }
-  } 
-}

src/com/yarrcad/cg/util/DirectoryDateMark.hx

-/*
- * This file is part of the CGML Compiler
- *
- * Copyright(c) 2010 Aleksey Fomkin <aleksey.fomkin@gmail.com>
- * http://bitbucket.org/yelbota/cgml-compiler
- *
- * This file may be licensed under the terms of of the
- * GNU General Public License Version 3 (the ``GPL'').
- *
- * Software distributed under the License is distributed
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
- * express or implied. See the GPL for the specific language
- * governing rights and limitations.
- *
- * You should have received a copy of the GPL along with this
- * program. If not, go to http://www.gnu.org/licenses/gpl.html
- * or write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-package com.yarrcad.cg.util;
-import sys.FileSystem;
-
-import sys.io.File;
-
-class DirectoryDateMark extends AbstractDateMark
-{
-  public function new(generatedRoot:String, sourceRoot:String)
-  {
-    super(generatedRoot, sourceRoot);
-  }
-  
-  override private function getDate(ns:String):Date
-  {
-    var filename = getFileWithMark(ns);
-    if (!FileSystem.exists(filename))
-      return Date.fromTime(0);
-    
-    return Date.fromString(File.getContent(filename));
-  }
-  
-  override private function setDate(ns:String, date:Date)
-  {
-    var f = File.write(getFileWithMark(ns), false);
-    
-    f.writeString(date.toString());
-    f.close();
-  }
-  
-  private function getFileWithMark(ns:String):String
-  {
-    return generatedRoot + "/" + ns.split(".").join("/") + ".modify_date";
-  }
-}

src/com/yarrcad/cg/util/FileDateMark.hx

-/*
- * This file is part of the CGML Compiler
- *
- * Copyright(c) 2010 Aleksey Fomkin <aleksey.fomkin@gmail.com>
- * http://bitbucket.org/yelbota/cgml-compiler
- *
- * This file may be licensed under the terms of of the
- * GNU General Public License Version 3 (the ``GPL'').
- *
- * Software distributed under the License is distributed
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
- * express or implied. See the GPL for the specific language
- * governing rights and limitations.
- *
- * You should have received a copy of the GPL along with this
- * program. If not, go to http://www.gnu.org/licenses/gpl.html
- * or write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
- 
-package com.yarrcad.cg.util;
-import sys.FileSystem;
-
-import sys.io.File;
-
-/**
- *  Date mark for single file modules, such as haxe.
- */
-class FileDateMark extends DirectoryDateMark
-{
-  override function getFileWithMark(ns:String):String
-  {
-    var sp = ns.split(".");
-    var module = sp.pop();
-    return generatedRoot + "/" + sp.join("/") + "/" + module + "modify_date";
-  }
-}

src/com/yarrcad/cg/writers/AS3Writer.hx

-/*
- * This file is part of the CGML Compiler
- *
- * Copyright(c) 2010 Aleksey Fomkin <aleksey.fomkin@gmail.com>
- * http://bitbucket.org/yelbota/cgml-compiler
- *
- * This file may be licensed under the terms of of the
- * GNU General Public License Version 3 (the ``GPL'').
- *
- * Software distributed under the License is distributed
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
- * express or implied. See the GPL for the specific language
- * governing rights and limitations.
- *
- * You should have received a copy of the GPL along with this
- * program. If not, go to http://www.gnu.org/licenses/gpl.html
- * or write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-package com.yarrcad.cg.writers;
-import com.yarrcad.cg.util.DirectoryDateMark;
-
-import sys.io.File;
-import sys.FileSystem;
-
-import com.yarrcad.cg.Ast;
-import haxe.FastList;
-
-using Lambda;
-
-class AS3Writer extends AbstractWriter
-{
-  var lastI:Int;
-  
-  public function new(targetDir:String, dateMark:DirectoryDateMark)
-  {
-    this.targetDir = targetDir;
-    this.dateMark = dateMark;
-    this.lastI = 0;
-  }
-  
-  override public function write(ast:Ast, addWarnings:Bool, addYarrnetInterface:Bool, addPrefix:String)
-  {
-    super.write(ast, addWarnings, addYarrnetInterface, addPrefix);
-
-    // Проверим, существует ли базовая папка.
-    if (!FileSystem.exists(targetDir))
-      FileSystem.createDirectory(targetDir);
-    
-    var opens = new Hash<Int>();
-    
-    for (node in ast.types)
-    {
-      if (Ast.getNodeTyped(node))
-        continue;
-        
-      var ns = Ast.getNodeNs(node);
-      var annotations = switch (node)
-      {
-        case Model(v): v.annotations;
-        case Variant(v): v.annotations;
-        default: null;
-      }
-      
-      if (annotations != null && (Lambda.has(annotations, "native") || Lambda.has(annotations, "basic")))
-        continue;
-   
-      if (!dateMark.getGenerationRequired(ns))
-        continue;
-        
-      var pp = ns.split(".");
-          
-      var path0 =  targetDir + "/" + pp.join("/") + "/";
-      var path = path0 + getNodeActualName(node) + ".as";
-
-      if (!FileSystem.exists(path))
-      {
-        var pathBuf = targetDir;      
-        for (dir in pp)
-        {
-          pathBuf += "/" + dir;
-          
-          if (!FileSystem.exists(pathBuf))
-            FileSystem.createDirectory(pathBuf);
-        }
-      }
-
-      // Строковый буфер с пакетом и целевыми импортами.
-      var rHead = new StringBuf();
-      
-      rHead.add("package " + pp.join(".") + " {");
-      
-      if (ast.uses.get(ns) != null)
-      for (imp in ast.uses.get(ns))
-      {
-        if (imp == "cgml.lang.basic")
-          continue;
-  
-        // Тут интересная ситуация. То, что в cgml является модулем в java
-        // является пакетом. По этому набор импортов у разных моделей в одном
-        // модуле будет разным. Необходимо проверить, фигурируют ли типы 
-        // указанные для модуле в моделе.
-        var used = false;
-
-        // Провери не наследует ли типа чего
-        var nodeType = Ast.getNodeType(node);
-        if (nodeType != Void)
-        {
-          var nodeTypeNs = Ast.getNodeNs(nodeType);
-          if (nodeTypeNs == imp)
-            used = true;
-        }
-          
-        // Проверим свойства
-        if (!used)
-        {
-          for (p in Ast.getNodeProperties(node))
-          {
-            if (p.type == Void)
-              continue;
-              
-            var pns = Ast.getNodeNs(p.type);
-            if (pns == imp)
-            {
-              used = true;
-              break;
-            }
-          }
-        }
-        
-        if (used)  
-          rHead.add("import " + imp + ".*;");
-      }
-
-      var rClass = new StringBuf();
-      rClass.add(rHead);
-      
-      switch (node)
-      {
-        case Model(v):
-        {
-          var body = writeModel(v);
-          rClass.add(body);
-          rClass.add("}"); // package end
-
-          var output = File.write(path, false);
-          output.writeString(codeFormat(rClass.toString()));
-          output.close();
-        }
-        case Variant(v):
-        {
-          var body = writeVariant(v);
-          rClass.add(body);
-          rClass.add("}"); // package end
-        
-          var output = File.write(path, false);
-          output.writeString(codeFormat(rClass.toString()));
-          output.close();
-        }
-        default: throw "Internal Error";
-      }
-      
-      dateMark.updateMark(ns);
-    }
-  }
-
-  //----------------------------------------------------------------------------
-  //
-  //  Скрытые методы
-  //
-  //----------------------------------------------------------------------------
- 
-  function getI()
-  {
-    return "_i" + Std.string(lastI++);
-  }
-  
-  function writeModel(model:Model):String
-  {
-    Sys.println(" a " + getActualName(model.name));
-    
-    var r = new StringBuf();
-    var bindable = model.annotations.has("bindable");
-
-    if (bindable)
-    {
-      r.add("import com.yarrcad.cgml.CollectionChangeBroadcaster;");
-      r.add("import mx.collections.ArrayCollection;");
-    }
-    
-    if (!model.typed)
-    {
-      r.add("import com.yarrcad.cgml.ObjectStorage;");
-      r.add("import com.yarrcad.cgml.option.*;");
-      r.add("import flash.utils.IDataInput;");
-      r.add("import flash.utils.IDataOutput;");
-    }
-
-    if ((model.type == Void || !model.typed) && addYarrnetInterface)
-      r.add("import com.yarrcad.net.IYarrnetModel;");
-
-    var ptn = Ast.getNodeTrueName(model.type);
-    var isListChild = Ast.getNodeIsList(model.type);
-
-    if (bindable)
-      r.add("[Bindable] ");
-    if (isListChild)
-      r.add("dynamic ");
-      
-    r.add("public class ");
-    r.add(getActualName(model.name));
-
-    if (isListChild)
-    {
-      r.add(" extends Vector.<");
-      r.add(getNodeActualName(model.type));
-      r.add(">");
-
-      if (addYarrnetInterface)
-        r.add(" implements IYarrnetModel");
-    }
-    else if (model.type != Void)
-    {
-      r.add(" extends ");
-      r.add(getNodeActualName(model.type));
-
-      if (addYarrnetInterface)
-        r.add(" implements IYarrnetModel");
-    }  
-    
-    r.add("{");
-
-    // Write default constructor
-    r.add("public function ");
-    r.add(getActualName(model.name));
-    r.add("() {");
-
-    for (prop in model.properties)
-    {
-      var propname = getActualName(prop.name, false);
-      
-      if (Ast.getNodeIsList(prop.type) && bindable)
-      {
-        r.add("__");
-        r.add(propname);
-        r.add("Broadcaster = new CollectionChangeBroadcaster(");
-        r.add('"'+propname+'"');
-        r.add(", this, ");
-        r.add(propname);
-        r.add(");");
-      }
-    }    
-
-    r.add("}");
-    
-    // Запишем свойства
-    for (prop in model.properties)
-    {
-      var propname = getActualName(prop.name, false);
-        
-      r.add("public var ");
-      r.add(propname);
-      r.add(":");
-      r.add(getNodeActualName(prop.type, prop.option, bindable));
-      r.add(";");
-
-      if (Ast.getNodeIsList(prop.type) && bindable)
-      {
-        r.add("private var __");
-        r.add(propname);
-        r.add("Broadcaster:CollectionChangeBroadcaster;");
-      }
-    }
-
-    if (!model.typed)
-    {
-      if (model.type != Void && !Ast.getNodeTyped(model.type))
-        r.add("override ");
-
-      r.add("public function write(__stream:IDataOutput, __obs:ObjectStorage=null):void{");
-      r.add("if (__obs == null) __obs = new ObjectStorage();");
-      r.add("write");
-      r.add(getActualName(model.name));
-      r.add("(__stream, __obs);}");
-
-      r.add("public function write");
-      r.add(getActualName(model.name));
-      r.add("(__stream:IDataOutput, __obs:ObjectStorage):void {");
-
-      r.add(getModelWriter([], model));
-      
-      r.add("}");
-    
-      if (model.type != Void && !Ast.getNodeTyped(model.type))
-        r.add("override ");
-
-      r.add("public function read(__stream:IDataInput, __obs:ObjectStorage=null):void {");
-      r.add("if (__obs == null) __obs = new ObjectStorage();");
-      r.add("read");
-      r.add(getActualName(model.name));
-      r.add("(__stream, __obs);}");
-
-      r.add("public function read");
-      r.add(getActualName(model.name));
-      r.add("(__stream:IDataInput, __obs:ObjectStorage):void {");
-      r.add(getModelReader([ ], model));
-      r.add("}");
-    }
-        
-    r.add("}");
-    
-    return r.toString();
-  }
-  
-  function getModelWriter(ochain:Array<String>, model:Model, t:Node=null):StringBuf
-  {
-    var r = new StringBuf();
-    var ptn = Ast.getNodeTrueName(model.type);
-    var isListChild = Ast.getNodeIsList(model.type);
-    
-    // Запишем используем родительскую писалку
-    if (model.type != Void)
-    {
-      if (ochain == null || ochain.length < 1)
-        ochain = [ "this" ];
-        
-      r.add(getPropWriter(ochain, model.type, false));
-    }
-
-    // Запишем свойства
-    for (prop in model.properties)
-    {
-      var oc = ochain.copy();
-      oc.push(prop.name);
-      r.add(getPropWriter(oc, prop.type, prop.option, t));
-    }
-    
-    return r;
-  }
-  
-  
-  function getModelReader(ochain:Array<String>, model:Model, t:Node=null)
-  {
-    var r = new StringBuf();
-    var ptn = Ast.getNodeTrueName(model.type);
-    var isListChild = Ast.getNodeIsList(model.type);
-    var bindable = model.annotations.has("bindable");
-
-    // Запишем используем родительскую читалкуу
-    if (model.type != Void)
-    {
-      if (ochain == null || ochain.length < 1)
-        ochain = [ "this" ];
-        
-      r.add(getPropReader(ochain, model.type, false, Void, false, false, bindable));
-    }
-
-    // Запишем свойства
-    for (prop in model.properties)
-    {
-      var oc = ochain.copy();
-      oc.push(prop.name);
-      r.add(getPropReader(oc, prop.type, prop.option, t, false, true, bindable));
-    }
-    
-    return r;
-  }
-
-  function writeVariant(variant:Variant):String
-  {
-    Sys.println(" a " + getActualName(variant.name));
-    var r = new StringBuf();
-
-    if (!variant.typed)
-    {
-      r.add("import flash.utils.IDataInput;");
-      r.add("import flash.utils.IDataOutput;");
-      r.add("import com.yarrcad.cgml.ObjectStorage;");
-    }
-
-    if (!variant.typed && addYarrnetInterface)
-      r.add("import com.yarrcad.net.IYarrnetModel;");
-
-    r.add("public final class " + getActualName(variant.name));
-    
-    if (addYarrnetInterface)
-      r.add(" implements IYarrnetModel ");
-    
-    r.add(" {");
-
-    // Write default constructor
-    r.add("public function ");
-    r.add(getActualName(variant.name));
-    r.add("(){}");
-    
-    var i = 0;
-    for (prop in variant.properties)
-    {
-      if (prop.type != Void)
-      {
-        r.add("private var ");
-        r.add(getActualName(prop