Skip to content

Commit

Permalink
Merge pull request #35 from unyt-org/fix-transform-scope
Browse files Browse the repository at this point in the history
Fix transform scope
  • Loading branch information
benStre authored Jan 18, 2024
2 parents 7924828 + 6b0fe0a commit 3430900
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 42 deletions.
27 changes: 9 additions & 18 deletions compiler/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2145,9 +2145,13 @@ export class Compiler {
SCOPE.b_index += Uint32Array.BYTES_PER_ELEMENT; // leave space for JMP
SCOPE.uint8.set(new Uint8Array(compiled), SCOPE.b_index)
SCOPE.b_index += compiled.byteLength;

},

insertInitBlockPlaceholder: (SCOPE: compiler_scope|extract_var_scope) => {
const insertIndex = SCOPE.b_index;
SCOPE.b_index += Uint32Array.BYTES_PER_ELEMENT; // leave space for JMP
return insertIndex
},

addValVarRefDeclaration: async (name:string, type:'val'|'var'|'ref'|'const', SCOPE:compiler_scope, init = false, init_brackets = false) => {
const INNER_SCOPE = SCOPE.inner_scope;
Expand Down Expand Up @@ -2219,23 +2223,10 @@ export class Compiler {
return Compiler.builder.addInitBlock(<compiler_scope>SCOPE, init_brackets) // async
}
else if (transform_scope) {
const temp_scope = <extract_var_scope>{
b_index: 0,
buffer: new ArrayBuffer(400),
inner_scope: {},
dynamic_indices: [],
inserted_values: new Map(),
preemptive_pointers: new Map(),
assignment_end_indices: new Set(),
options: SCOPE.options
}
temp_scope.uint8 = new Uint8Array(temp_scope.buffer);
temp_scope.data_view = new DataView(temp_scope.buffer);
Compiler.builder.insert_transform_scope(temp_scope, transform_scope);
const compiled = temp_scope.uint8.slice(0,temp_scope.b_index)

Compiler.builder.handleRequiredBufferSize(SCOPE.b_index+compiled.byteLength+1, SCOPE);
Compiler.builder.insertInitBlock(SCOPE, compiled.buffer);
const insertIndex = Compiler.builder.insertInitBlockPlaceholder(SCOPE);
Compiler.builder.insert_transform_scope(SCOPE, transform_scope);
const size = SCOPE.b_index-insertIndex-Uint32Array.BYTES_PER_ELEMENT;
SCOPE.data_view.setUint32(insertIndex, size, true);
}
else return Compiler.builder.addInitBlockForValue(SCOPE, value) // sync
}
Expand Down
52 changes: 34 additions & 18 deletions js_adapter/js_class_adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,14 +384,13 @@ export class Decorators {
let type: Type;

// get template type
if (typeof params[0] == "string") {
const typeString = params[0].replace(/^\</,'').replace(/\>$/,'')
type = Type.get(typeString.includes(":") ? typeString : "ext:"+typeString)
if (typeof params[0] == "string" || params[0] instanceof Type) {
type = normalizeType(params[0], false, "ext");
}
else if (params[0] instanceof Type) type = params[0];
else if (original_class[METADATA]?.[Decorators.FORCE_TYPE]?.constructor) type = original_class[METADATA]?.[Decorators.FORCE_TYPE]?.constructor
else type = Type.get("ext", original_class.name);


// return new templated class
return createTemplateClass(original_class, type);
}
Expand All @@ -417,11 +416,9 @@ export class Decorators {
let type: Type;

// get template type
if (typeof params[0] == "string") {
const typeString = params[0].replace(/^\</,'').replace(/\>$/,'')
type = Type.get(typeString.includes(":") ? typeString : "ext:"+typeString)
if (typeof params[0] == "string" || params[0] instanceof Type) {
type = normalizeType(params[0], false, "ext");
}
else if (params[0] instanceof Type) type = params[0];
else if (original_class[METADATA]?.[Decorators.FORCE_TYPE]?.constructor) type = original_class[METADATA]?.[Decorators.FORCE_TYPE]?.constructor
else type = Type.get("ext", original_class.name);

Expand Down Expand Up @@ -488,15 +485,9 @@ export class Decorators {

/** @type(type:string|DatexType)/ (namespace:name)
* sync class with type */
static type(value:any, name:context_name, kind:context_kind, is_static:boolean, is_private:boolean, setMetadata:context_meta_setter, getMetadata:context_meta_getter, params:[(string|Type)?] = []) {

// handle decorator
if (typeof params[0] == "string") {
const [typeName, paramsString] = params[0].replace(/^\</,'').replace(/\>$/,'').match(/^(\w*)(?:\((.*)\))?$/)?.slice(1) ?? [];
const parsedParams = paramsString ? JSON.parse(`[${paramsString}]`) : undefined;
setMetadata(Decorators.FORCE_TYPE, Type.get(typeName, parsedParams))
}
else if (params[0] instanceof Type) setMetadata(Decorators.FORCE_TYPE, params[0])
static type(value:any, name:context_name, kind:context_kind, is_static:boolean, is_private:boolean, setMetadata:context_meta_setter, getMetadata:context_meta_getter, params:[(string|Type)] = []) {
const type = normalizeType(params[0]);
setMetadata(Decorators.FORCE_TYPE, type)
}

/** @from(type:string|DatexType): sync class from type */
Expand Down Expand Up @@ -574,7 +565,32 @@ export class Decorators {
}
}

globalThis.Decorators = Decorators;
/**
* Converts strings into Datex.Type and checks if type parameters are allowed
* @param type
* @param allowTypeParams
* @returns
*/
function normalizeType(type:Type|string, allowTypeParams = true, defaultNamespace = "std") {
if (typeof type == "string") {
// extract type name and parameters
const [typeName, paramsString] = type.replace(/^\</,'').replace(/\>$/,'').match(/^((?:\w+\:)?\w*)(?:\((.*)\))?$/)?.slice(1) ?? [];
if (paramsString && !allowTypeParams) throw new Error(`Type parameters not allowed (${type})`);

// TODO: only json-compatible params are allowed for now to avoid async
const parsedParams = paramsString ? JSON.parse(`[${paramsString}]`) : undefined;
return Type.get(typeName.includes(":") ? typeName : defaultNamespace+":"+typeName, parsedParams)
}
else if (type instanceof Type) {
if (!allowTypeParams && type.parameters?.length) throw new Error(`Type parameters not allowed (${type})`);
return type
}
else {
console.log(type)
throw new Error("Invalid type")
}
}


const initialized_static_scope_classes = new Map<Function,StaticScope>();

Expand Down
6 changes: 3 additions & 3 deletions js_adapter/legacy_decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ export function each(...args:any[]): any {
return handleDecoratorArgs(args, Decorators.each);
}

export function sync(type:string|Type):any
export function sync(type:string):any
export function sync(target: any, name?: string, method?:any):any
export function sync(...args:any[]): any {
return handleDecoratorArgs(args, Decorators.sync);
Expand All @@ -237,7 +237,7 @@ export function sync(...args:any[]): any {
/**
* @deprecated use \@sync
*/
export function template(type:string|Type):any
export function template(type:string):any
/**
* @deprecated use \@sync
*/
Expand Down Expand Up @@ -288,7 +288,7 @@ export function anonymous(...args:any[]) {

export function type(type:string|Type):any
export function type(...args:any[]): any {
return handleDecoratorArgs(args, Decorators.type);
return handleDecoratorArgs(args, Decorators.type, true);
}

export function assert(assertion:(val:any)=>boolean|string|undefined|null):any
Expand Down
6 changes: 3 additions & 3 deletions types/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -695,12 +695,12 @@ export class Type<T = any> extends ExtensibleFunction {
}

public static assertMatches<T extends Type>(value:RefOrValue<any>, type:type_clause): asserts value is (T extends Type<infer TT> ? TT : any) {
const res = Type.matchesType(Type.ofValue(value), type, value, true);
const res = Type.matches(value, type, true);
if (!res) throw new ValueError("Value must be of type " + type)
}

// check if root type of value matches exactly
public static matches<T extends Type>(value:RefOrValue<any>, type:type_clause): value is (T extends Type<infer TT> ? TT : any) {
public static matches<T extends Type>(value:RefOrValue<any>, type:type_clause, throwInvalidAssertion = false): value is (T extends Type<infer TT> ? TT : any) {
value = Ref.collapseValue(value, true, true);
// value has a matching DX_TEMPLATE
if (type instanceof Type && type.template && value[DX_TEMPLATE] && this.matchesTemplate(value[DX_TEMPLATE], type.template)) return true;
Expand All @@ -712,7 +712,7 @@ export class Type<T = any> extends ExtensibleFunction {
return value.length <= type.parameters[0];
}

return Type.matchesType(Type.ofValue(value), type, value);
return Type.matchesType(Type.ofValue(value), type, value, throwInvalidAssertion);
}

public static extends(type:Type, extends_type:type_clause){
Expand Down

0 comments on commit 3430900

Please sign in to comment.