Skip to content

Commit

Permalink
Updated to adl 0.13.8
Browse files Browse the repository at this point in the history
  • Loading branch information
timbod7 committed Aug 31, 2020
1 parent 38aba4e commit 5c9e7ae
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 27 deletions.
2 changes: 1 addition & 1 deletion scripts/adlc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

set -e

adlversion=0.13.2
adlversion=0.13.8

if [ "$(uname)" == "Darwin" ]; then
platform=osx
Expand Down
10 changes: 10 additions & 0 deletions src/ADL/Sys/Adlast.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ module ADL.Sys.Adlast(
TypeExpr(..),
TypeRef(..),
Union(..),
mkDecl,
mkField,
mkModule,
mkNewType,
mkScopedDecl,
mkScopedName,
mkStruct,
mkTypeDef,
mkTypeExpr,
mkUnion,
) where

import ADL.Core
Expand Down
5 changes: 5 additions & 0 deletions src/ADL/Sys/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ module ADL.Sys.Types(
MapEntry(..),
Maybe,
Pair,
Result,
Set,
mkMapEntry,
) where

import ADL.Core
Expand Down Expand Up @@ -61,4 +63,7 @@ type Maybe = Prelude.Maybe
type Pair a b = (a,b)


type Result t e = Prelude.Either e t


type Set v = Set.Set v
2 changes: 1 addition & 1 deletion test/adl-gen/runtime/adl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export interface DeclResolver {
};

export function declResolver(...astMaps : ({[key:string] : AST.ScopedDecl})[]) {
const astMap = {};
const astMap : {[key:string] : AST.ScopedDecl} = {};
for (let map of astMaps) {
for (let scopedName in map) {
astMap[scopedName] = map[scopedName];
Expand Down
79 changes: 54 additions & 25 deletions test/adl-gen/runtime/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,25 @@ import * as AST from './sys/adlast';
import * as b64 from 'base64-js';
import {isVoid, isEnum, scopedNamesEqual} from './utils';

/** A type alias for json serialised values */
type Json = {}|null;
/** A type for json serialised values */

export type Json = {} | null;
export type JsonObject = { [member: string]: Json };
export type JsonArray = Json[];

function asJsonObject(jv: Json): JsonObject | undefined {
if (jv instanceof Object && !(jv instanceof Array)) {
return jv as JsonObject;
}
return undefined;
}

function asJsonArray(jv: Json): JsonArray | undefined{
if(jv instanceof Array) {
return jv as JsonArray;
}
return undefined;
}

/** A type alias for values of an Unknown type */
type Unknown = {}|null;
Expand Down Expand Up @@ -57,7 +74,7 @@ export interface JsonParseException {

// Map a JsonException to an Error value
export function mapJsonException(exception:{}): {} {
if (exception && exception['kind'] == "JsonParseException") {
if (exception && (exception as {kind:string})['kind'] == "JsonParseException") {
const jserr: JsonParseException = exception as JsonParseException;
return new Error(jserr.getMessage());
} else {
Expand Down Expand Up @@ -161,14 +178,14 @@ function primitiveJsonBinding(dresolver : DeclResolver, ptype : string, params :
function identityJsonBinding<T>(expected : string, predicate : (json : Json) => boolean) : JsonBinding0<T>{

function toJson(v : T) : Json {
return v;
return (v as Unknown as Json);
}

function fromJson(json : Json) : T {
if( !predicate(json)) {
throw jsonParseException("expected " + expected);
}
return json as T;
return json as Unknown as T;
}

return {toJson, fromJson};
Expand Down Expand Up @@ -197,11 +214,12 @@ function vectorJsonBinding(dresolver : DeclResolver, texpr : AST.TypeExpr, bound
}

function fromJson(json : Json) : Unknown[] {
if (!(json instanceof Array)) {
const jarr = asJsonArray(json);
if (jarr == undefined) {
throw jsonParseException('expected an array');
}
let result : Unknown[] = [];
json.forEach( (eljson,i) => {
jarr.forEach( (eljson:Json,i:number) => {
try {
result.push(elementBinding().fromJson(eljson));
} catch(e) {
Expand All @@ -223,21 +241,22 @@ function stringMapJsonBinding(dresolver : DeclResolver, texpr : AST.TypeExpr, bo
const elementBinding = once(() => buildJsonBinding(dresolver, texpr, boundTypeParams));

function toJson(v : StringMap<Unknown>) : Json {
const result = {};
const result: JsonObject = {};
for (let k in v) {
result[k] = elementBinding().toJson(v[k]);
}
return result;
}

function fromJson(json : Json) : StringMap<Unknown> {
if (!(json instanceof Object)) {
const jobj = asJsonObject(json);
if (!jobj) {
throw jsonParseException('expected an object');
}
let result = {};
for (let k in json) {
let result: JsonObject = {};
for (let k in jobj) {
try {
result[k] = elementBinding().fromJson(json[k]);
result[k] = elementBinding().fromJson(jobj[k]);
} catch(e) {
if (isJsonParseException(e)) {
e.pushField(k);
Expand Down Expand Up @@ -296,22 +315,24 @@ function structJsonBinding(dresolver : DeclResolver, struct : AST.Struct, params
});
});

function toJson(v: Unknown) : Json {
const json = {};
function toJson(v0: Unknown) : Json {
const v = v0 as {[key:string]:Unknown};
const json: JsonObject = {};
fieldDetails.forEach( (fd) => {
json[fd.field.serializedName] = fd.jsonBinding().toJson(v && v[fd.field.name]);
});
return json;
}

function fromJson(json: Json): Unknown {
if (!(json instanceof Object)) {
const jobj = asJsonObject(json);
if (!jobj) {
throw jsonParseException("expected an object");
}

const v = {};
const v : {[member:string]: Unknown} = {};
fieldDetails.forEach( (fd) => {
if (json[fd.field.serializedName] === undefined) {
if (jobj[fd.field.serializedName] === undefined) {
const defaultv = fd.buildDefault();
if (defaultv === null) {
throw jsonParseException("missing struct field " + fd.field.serializedName );
Expand All @@ -320,7 +341,7 @@ function structJsonBinding(dresolver : DeclResolver, struct : AST.Struct, params
}
} else {
try {
v[fd.field.name] = fd.jsonBinding().fromJson(json[fd.field.serializedName]);
v[fd.field.name] = fd.jsonBinding().fromJson(jobj[fd.field.serializedName]);
} catch(e) {
if (isJsonParseException(e)) {
e.pushField(fd.field.serializedName);
Expand All @@ -337,7 +358,7 @@ function structJsonBinding(dresolver : DeclResolver, struct : AST.Struct, params

function enumJsonBinding(_dresolver : DeclResolver, union : AST.Union, _params : AST.TypeExpr[], _boundTypeParams : BoundTypeParams ) : JsonBinding0<Unknown> {
const fieldSerializedNames : string[] = [];
const fieldNumbers = {};
const fieldNumbers : {[key:string]:number} = {};
union.fields.forEach( (field,i) => {
fieldSerializedNames.push(field.serializedName);
fieldNumbers[field.serializedName] = i;
Expand All @@ -361,12 +382,18 @@ function enumJsonBinding(_dresolver : DeclResolver, union : AST.Union, _params :
return {toJson, fromJson};
}

interface FieldDetails {
field : AST.Field;
isVoid : boolean;
jsonBinding : () => JsonBinding0<Unknown>;
};

function unionJsonBinding(dresolver : DeclResolver, union : AST.Union, params : AST.TypeExpr[], boundTypeParams : BoundTypeParams ) : JsonBinding0<Unknown> {


const newBoundTypeParams = createBoundTypeParams(dresolver, union.typeParams, params, boundTypeParams);
const detailsByName = {};
const detailsBySerializedName = {};
const detailsByName : {[key: string]: FieldDetails} = {};
const detailsBySerializedName : {[key: string]: FieldDetails} = {};
union.fields.forEach( (field) => {
const details = {
field : field,
Expand All @@ -383,7 +410,7 @@ function unionJsonBinding(dresolver : DeclResolver, union : AST.Union, params :
if (details.isVoid) {
return details.field.serializedName;
} else {
const result = {};
const result: JsonObject = {};
result[details.field.serializedName] = details.jsonBinding().toJson(v.value);
return result;
}
Expand All @@ -404,13 +431,15 @@ function unionJsonBinding(dresolver : DeclResolver, union : AST.Union, params :
throw jsonParseException("union field " + json + "needs an associated value");
}
return { kind : details.field.name };
} else if (json instanceof Object) {
for (let k in json) {
}
const jobj = asJsonObject(json);
if (jobj) {
for (let k in jobj) {
let details = lookupDetails(k);
try {
return {
kind : details.field.name,
value : details.jsonBinding().fromJson(json[k])
value : details.jsonBinding().fromJson(jobj[k])
}
} catch(e) {
if (isJsonParseException(e)) {
Expand Down
24 changes: 24 additions & 0 deletions test/adl-gen/runtime/sys/adlast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ export interface TypeRef_Reference {

export type TypeRef = TypeRef_Primitive | TypeRef_TypeParam | TypeRef_Reference;

export interface TypeRefOpts {
primitive: Ident;
typeParam: Ident;
reference: ScopedName;
}

export function makeTypeRef<K extends keyof TypeRefOpts>(kind: K, value: TypeRefOpts[K]) { return {kind, value}; }

export interface TypeExpr {
typeRef: TypeRef;
parameters: TypeExpr[];
Expand Down Expand Up @@ -173,6 +181,15 @@ export interface DeclType_Newtype_ {

export type DeclType = DeclType_Struct_ | DeclType_Union_ | DeclType_Type_ | DeclType_Newtype_;

export interface DeclTypeOpts {
struct_: Struct;
union_: Union;
type_: TypeDef;
newtype_: NewType;
}

export function makeDeclType<K extends keyof DeclTypeOpts>(kind: K, value: DeclTypeOpts[K]) { return {kind, value}; }

export interface Decl {
name: Ident;
version: sys_types.Maybe<number>;
Expand Down Expand Up @@ -226,6 +243,13 @@ export interface Import_ScopedName {

export type Import = Import_ModuleName | Import_ScopedName;

export interface ImportOpts {
moduleName: ModuleName;
scopedName: ScopedName;
}

export function makeImport<K extends keyof ImportOpts>(kind: K, value: ImportOpts[K]) { return {kind, value}; }

export interface Module {
name: ModuleName;
imports: Import[];
Expand Down
39 changes: 39 additions & 0 deletions test/adl-gen/runtime/sys/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ export interface Either_Right<_T1, T2> {

export type Either<T1, T2> = Either_Left<T1, T2> | Either_Right<T1, T2>;

export interface EitherOpts<T1, T2> {
left: T1;
right: T2;
}

export function makeEither<T1, T2, K extends keyof EitherOpts<T1, T2>>(kind: K, value: EitherOpts<T1, T2>[K]) { return {kind, value}; }

export interface Maybe_Nothing<_T> {
kind: 'nothing';
}
Expand All @@ -39,6 +46,13 @@ export interface Maybe_Just<T> {

export type Maybe<T> = Maybe_Nothing<T> | Maybe_Just<T>;

export interface MaybeOpts<T> {
nothing: null;
just: T;
}

export function makeMaybe<T, K extends keyof MaybeOpts<T>>(kind: K, value: MaybeOpts<T>[K]) { return {kind, value}; }

export interface Error_Value<T> {
kind: 'value';
value: T;
Expand All @@ -50,6 +64,31 @@ export interface Error_Error<_T> {

export type Error<T> = Error_Value<T> | Error_Error<T>;

export interface ErrorOpts<T> {
value: T;
error: string;
}

export function makeError<T, K extends keyof ErrorOpts<T>>(kind: K, value: ErrorOpts<T>[K]) { return {kind, value}; }

export interface Result_Ok<T, _E> {
kind: 'ok';
value: T;
}
export interface Result_Error<_T, E> {
kind: 'error';
value: E;
}

export type Result<T, E> = Result_Ok<T, E> | Result_Error<T, E>;

export interface ResultOpts<T, E> {
ok: T;
error: E;
}

export function makeResult<T, E, K extends keyof ResultOpts<T, E>>(kind: K, value: ResultOpts<T, E>[K]) { return {kind, value}; }

export interface MapEntry<K, V> {
key: K;
value: V;
Expand Down
28 changes: 28 additions & 0 deletions test/adl-gen/sys/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,33 @@ export function texprError<T>(texprT : ADL.ATypeExpr<T>): ADL.ATypeExpr<Error<T>
return {value : {typeRef : {kind: "reference", value : {moduleName : "sys.types",name : "Error"}}, parameters : [texprT.value]}};
}

export interface Result_Ok<T, _E> {
kind: 'ok';
value: T;
}
export interface Result_Error<_T, E> {
kind: 'error';
value: E;
}

export type Result<T, E> = Result_Ok<T, E> | Result_Error<T, E>;

export interface ResultOpts<T, E> {
ok: T;
error: E;
}

export function makeResult<T, E, K extends keyof ResultOpts<T, E>>(kind: K, value: ResultOpts<T, E>[K]) { return {kind, value}; }

const Result_AST : ADL.ScopedDecl =
{"moduleName":"sys.types","decl":{"annotations":[],"type_":{"kind":"union_","value":{"typeParams":["T","E"],"fields":[{"annotations":[],"serializedName":"ok","default":{"kind":"nothing"},"name":"ok","typeExpr":{"typeRef":{"kind":"typeParam","value":"T"},"parameters":[]}},{"annotations":[],"serializedName":"error","default":{"kind":"nothing"},"name":"error","typeExpr":{"typeRef":{"kind":"typeParam","value":"E"},"parameters":[]}}]}},"name":"Result","version":{"kind":"nothing"}}};

export const snResult: ADL.ScopedName = {moduleName:"sys.types", name:"Result"};

export function texprResult<T, E>(texprT : ADL.ATypeExpr<T>, texprE : ADL.ATypeExpr<E>): ADL.ATypeExpr<Result<T, E>> {
return {value : {typeRef : {kind: "reference", value : {moduleName : "sys.types",name : "Result"}}, parameters : [texprT.value, texprE.value]}};
}

export interface MapEntry<K, V> {
key: K;
value: V;
Expand Down Expand Up @@ -161,6 +188,7 @@ export const _AST_MAP: { [key: string]: ADL.ScopedDecl } = {
"sys.types.Either" : Either_AST,
"sys.types.Maybe" : Maybe_AST,
"sys.types.Error" : Error_AST,
"sys.types.Result" : Result_AST,
"sys.types.MapEntry" : MapEntry_AST,
"sys.types.Map" : Map_AST,
"sys.types.Set" : Set_AST
Expand Down

0 comments on commit 5c9e7ae

Please sign in to comment.