Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a javascript backend #30

Closed
timbod7 opened this issue Nov 21, 2016 · 3 comments
Closed

Implement a javascript backend #30

timbod7 opened this issue Nov 21, 2016 · 3 comments

Comments

@timbod7
Copy link
Collaborator

timbod7 commented Nov 21, 2016

Unlike other language backends it is envisaged that a javascript backend won't generate type definitions - rather it will generate records of auxiliary functions to assist with each ADL type. For example, given this ADL:

module mymodel
{
  struct User
  {
     String name;
     String address;
     Int32 age;
  };
};

We might generate code like:

//----------------------------------------------------------------------
// adl/primitives.js   (hand written library code)

var String = {
  validate : function(v) {return typeof(v) == "string";},
  default : function() {return "";},
  copy : function(v) {return v;},
  equal : function(v1, v2) {return v1 == v2;}
};

var Int32 = {
  validate : function(v) {return typeof(v) == "number";},
  default : function() {return 0;},
  copy : function(v) {return return v;},
  equal : function(v1, v2) {return v1 == v2;}
};

//----------------------------------------------------------------------
// mymodel.js (machine generated)


var primitives = require('adl/primitives.js');

var User = {
  validate : function(v) {
    return primitives.String.validate(v.name)
      && primitives.String.validate(v.address)
      && primitives.Int32.validate(v.age);
  },
  default : function() {
    return {
      name : primitives.String.default(),
      address : primitives.String.default(),
      age : primitives.Int32.default()
    };
  },
  copy : function(v) {
    return {
      name : primitives.String.copy(v.name),
      address : primitives.String.copy(v.address),
      age : primitives.Int32.copy(v.age)
    };
  },
  equals : function(v1, v2) {
    return primitives.String.equals(v1.name, v2.name)
      && primitives.String.equals(v1.address, v2.name)
      && primitives.Int32.equals(v1.age, v2.age);
  }
}

Of course, there are lots of complexities to be dealt with:

  • explicit defaults in the ADL
  • generic types
  • custom type definitions.

etc

@timbod7 timbod7 changed the title Javascript Backend Implement a javascript backend Nov 21, 2016
@timbod7
Copy link
Collaborator Author

timbod7 commented Nov 21, 2016

Actually, the generated code above is styled after that we generate for statically typed backends. We could take advantage of dynamically typed helper functions, and generate much less, something like:

//----------------------------------------------------------------------
// adl/primitives.js   (hand written)

var String = {
  validate : function(v) {return typeof(v) == "string";},
  default : function() {return "";},
  copy : function(v) {return v;},
  equal : function(v1, v2) {return v1 == v2;}
};

var Int32 = {
  validate : function(v) {return typeof(v) == "number";},
  default : function() {return 0;},
  copy : function(v) {return return v;},
  equal : function(v1, v2) {return v1 == v2;}
};


function structValidate(fieldTypes) {
  return function(v) {
    for(var field in fieldTypes) {
      if(!fieldTypes[field].validate(v[field])) {
        return false;
      }
    }
    return true;
  };
}

function structDefault(fieldTypes) {
  return function() {
    var result = {};
    for(var field in fieldTypes) {
      result[field] = fieldTypes[field].default();
    }
    return result;
  };
}

function structCopy(fieldTypes) {
  return function(v) {
    var result = {};
    for(var field in fieldTypes) {
      result[field] = fieldTypes[field].copy(v[field]);
    }
    return result;
  };
}

function structEquals(fieldTypes) {
  return function(v1,v2) {
    for(var field in fieldTypes) {
      if(!fieldTypes[field].equal(v1[field], v2[field])) {
        return false;
      }
    }
    return true;
  };
}

//----------------------------------------------------------------------
// mymodel.js (machine generated)


var primitives = require('adl/primitives.js');

var User_fields = {
  "name" : primitives.String,
  "address" : primitives.String,
  "age" : primitives.Int32
};
  

var User = {
  validate : primitives.structValidate(User_fields),
  default : primitives.structDefault(User_fields),
  copy : primitives.structCopy(User_fields),
  equals : primitives.structEquals(User_fields)
}

@timbod7
Copy link
Collaborator Author

timbod7 commented Nov 22, 2016

Actually, generics will require functions, so probably best to use functions everywhere, ie this ADL:

module mymodel
{
  struct User<T>
  {
     String name;
     String address;
     Int32 age;
     T details;
  };
};

would generate code like this:

//----------------------------------------------------------------------
// mymodel.js (machine generated)


var primitives = require('adl/primitives.js');

function User_fields(T) {
  return {
    "name" : primitives.String,
    "address" : primitives.String,
    "age" : primitives.Int32,
    "details" : T
  };
};

function User(T) {
  var fieldTypes = User_fields(T);
  return {
    validate : primitives.structValidate(fieldTypes),
    default : primitives.structDefault(fieldTypes),
    copy : primitives.structCopy(fieldTypes),
    equals : primitives.structEquals(fieldTypes)
  };
}

and monomorphic types (ie those without type parameters) would be functions with no arguments.

@timbod7
Copy link
Collaborator Author

timbod7 commented Apr 25, 2017

This has been done, although in a very different way. We generate a javascript translation of the ADL data model, which can be processed generically in javascript.

@timbod7 timbod7 closed this as completed Apr 25, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant