I'm trying to inspect an object to see what properties it has. Is there a method to print an object to the stdout?
There is no method to convert an object into a string. You can do ((ObjectClass) obj.get_type().class_ref()).list_properties() to inspect the properties of a class (not all the fields though, only properties). You might like something like this:
public void type_info<T>() {
var type = typeof(T);
TypeQuery query;
type.query(out query);
stdout.printf("%s %c%c%c%C%C%C%C%C%C%C%C size(class = %u instance = %u)\n", type.name(),
type.is_object() ? 'o' : '-',
type.is_abstract() ? 'a' : '-',
type.is_classed() ? 'c' : '-',
type.is_derivable() ? (type.is_deep_derivable() ? 'D' : 'd') : '-',
type.is_derived() ? 'v' : '-',
type.is_fundamental() ? 'F' : '-',
type.is_instantiatable() ? 'N' : '-',
type.is_interface() ? 'i' : '-',
type.is_value_type() ? 's' : '-',
type.is_enum() ? 'e' : '-',
type.is_flags() ? 'f' : '-',
query.class_size,
query.instance_size);
if (type.is_object()) {
stdout.printf("class %s", type.name());
for(var parent = type.parent(); parent != Type.INVALID; parent = parent.parent()) {
stdout.printf(" : %s", parent.name());
}
stdout.printf(" {\n");
foreach (var property in ((ObjectClass)type.class_ref()).list_properties()) {
stdout.printf("\t%s :: %s -- %s\n", property.name, property.value_type.name(), property.get_blurb());
}
stdout.printf("}\n");
}
}
Related
Hi I am using a custom function to format urls in google sheets:
/*
* Formats the page urls
*/
function URLS(page_url_list){
const urls = [];
for(let i = 0; i < page_url_list.pages.length; i++){
urls.push(page_url_list.pages[i].page_url + "\n");
}
return urls;
}
When I try to use it in google sheets
=URLS({
"pages" : [
{
"id" : 0,
"page_url" : "..."
}
]
})
I am getting a formula parse error
Object is not supported by formula, you may need to change it into a JSON string and then do JSON.parse in your function.
=URLS("{
""pages"" : [
{
""id"" : 0,
""page_url"" : ""...""
}
]
}")
or
=URLS("{
'pages' : [
{
'id' : 0,
'page_url' : '...'
}
]
}")
and replace ' with " in you function before doing JSON.parse.
When I run my code, I get an index out of range error. The same problem also occurs at the ensures statement.
My code:
datatype CACHE_STATE = I| S| E
datatype MSG_CMD = Empty| ReqS| ReqE| Inv| InvAck| GntS| GntE
type NODE=nat
type DATA=nat
type boolean=bool
class class_0 {
var
Data : DATA,
Cmd : MSG_CMD
}
class class_1 {
var
Data : DATA,
State : CACHE_STATE
}
class TopC{
var
AuxData : DATA,
MemData : DATA,
CurPtr : NODE,
CurCmd : MSG_CMD,
ExGntd : boolean,
ShrSet : array<boolean>,
InvSet : array<boolean>,
Chan3 : array<class_0 > ,
Chan2 : array<class_0 > ,
Chan1 : array<class_0 > ,
Cache : array<class_1 > }
method n_RecvInvAck(top:TopC,i:nat, N0:nat,p1:nat,p2:nat )
requires 0<= i<N0
requires top.Chan3.Length ==N0
requires top.ShrSet.Length ==N0
requires N0>0
requires 0<= p1 <top.Chan3.Length
requires 0<= p2 <top.Chan3.Length
requires p1
requires N0>0
requires (i==p2)
requires ((top.Chan3[i].Cmd == InvAck) && (!(top.CurCmd == Empty)))
modifies top.Chan3[i]
modifies top.ShrSet
modifies top
ensures (!((top.ShrSet[p1] == true) && (top.ExGntd == true) &&
(top.ShrSet[p2] == true)))
{
top.Chan3[i].Cmd := Empty;
top.ShrSet[i] := false;
if (top.ExGntd == true) {
top.ExGntd := false;
top.MemData := top.Chan3[i].Data;
}
}
The problem is that the method modifies top, which means it might allocated a totally different array for top.ShrSet, which might have a different length.
You can add the line
ensures top.ShrSet == old(top.ShrSet)
before the other ensures clause to fix this problem.
I've got a similar list:
list = [',99', ',48', ',48', ',44', ',80', ',82', ',88', ',90', '1,1']
I just want the number to the right of the comma, but when I try splitting:
newList = list.split(',')
I get:
AttributeError: 'list' object has no attribute 'split'
here split will not work because javascript method .split() is to convert string into array and but here list is an object. you can try console.log(typeof variable); to check type of any variable.
So here you can simply use jquery function .each() most common function used for traversing an javascript object.
Try below solution:
var list = [',99', ',48', ',48', ',44', ',80', ',82', ',88', ',90', '1,1'];
var new_list = [];
$(list).each(function( index, item ) {
var item_array = item.split(',');
$(item_array).each(function( i, num ) {
if(num && num != '' && typeof num != 'undefined'){
new_list.push(num);
}
});
});
then use new_list instead of list as it will contain desired output:
["99", "48", "48", "44", "80", "82", "88", "90", "1", "1"]
OR can try alternate way:
var list = [',99', ',48', ',48', ',44', ',80', ',82', ',88', ',90', '1,1'];
var list_str = list.toString();
list = list_str.split(',');
list = list.filter(function(item){
if(!!item){
return item;
}
});
In a JvmModelInferrer, when constructing the body of a method or constructor, how do you insert both an XExpression from the grammar
body = op.body
and additional "boilerplate" code, for example
body = [
append(
'''
System.out.println("BOILERPLATE");
'''
)
]
I can achieve either but not both.
For a minimal working example, consider the following canonical Xbase grammar,
grammar org.example.xbase.entities.Entities with org.eclipse.xtext.xbase.Xbase
generate entities "http://www.example.org/xbase/entities/Entities"
Model:
importSection=XImportSection?
entities+=Entity*;
Entity:
'entity' name=ID ('extends' superType=JvmParameterizedTypeReference)? '{'
attributes += Attribute*
operations += Operation*
'}';
Attribute:
'attr' (type=JvmTypeReference)? name=ID ('=' initexpression=XExpression)? ';';
Operation:
'op' (type=JvmTypeReference)? name=ID
'(' (params+=FullJvmFormalParameter (',' params+=FullJvmFormalParameter)*)? ')'
body=XBlockExpression;
and JvmModelInferrer,
package org.example.xbase.entities.jvmmodel
import com.google.inject.Inject
import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
import org.example.xbase.entities.entities.Entity
class EntitiesJvmModelInferrer extends AbstractModelInferrer {
#Inject extension JvmTypesBuilder
def dispatch void infer(Entity entity, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
acceptor.accept(entity.toClass("entities."+entity.name)) [
documentation = entity.documentation
if (entity.superType != null)
superTypes += entity.superType.cloneWithProxies
entity.attributes.forEach[
a |
val type = a.type ?: a.initexpression?.inferredType
members += a.toField(a.name, type) [
documentation = a.documentation
if (a.initexpression != null)
initializer = a.initexpression
]
members += a.toGetter(a.name, type)
members += a.toSetter(a.name, type)
]
entity.operations.forEach[
op |
members += op.toMethod(op.name, op.type ?: inferredType) [
documentation = op.documentation
for (p : op.params) {
parameters += p.toParameter(p.name, p.parameterType)
}
// body = [
// append(
// '''
// System.out.println("BOILERPLATE");
// '''
// )
// ]
body = op.body
]
]
]
}
}
As the comments suggest, I would like to insert "boilerplate" code into the body of the method, before the XExpression itself. While I can insert the boilerplate, or the expression, I cannot work out how to do both.
this does not work. the only thing you can do is to infer two methods
methodWithBoilerplate() {
//pre
methodwithoutboilerplate
//post
}
methodwithoutboilerplate() {
usercode goes here
}
for the first use body = '''code here'''
for the second use body = exp.body
This is the code that I have:
%lex
%options flex
%{
// Used to store the parsed data
if (!('regions' in yy)) {
yy.regions = {
settings: {},
tables: [],
relationships: []
};
}
%}
text [a-zA-Z][a-zA-Z0-9]*
%%
\n\s* return 'NEWLINE';
[^\S\n]+ ; // ignore whitespace other than newlines
"." return '.';
"," return ',';
"-" return '-';
"=" return '=';
"=>" return '=>';
"<=" return '<=';
"[" return '[';
"settings]" return 'SETTINGS';
"tables]" return 'TABLES';
"relationships]" return 'RELATIONSHIPS';
"]" return ']';
{text} return 'TEXT';
<<EOF>> return 'EOF';
/lex
%left ','
%start source
%%
source
: content EOF
{
console.log(yy.regions);
console.log("\n" + JSON.stringify(yy.regions));
return yy.regions;
}
| NEWLINE content EOF
{
console.log(yy.regions);
console.log("\n" + JSON.stringify(yy.regions));
return yy.regions;
}
| NEWLINE EOF
| EOF
;
content
: '[' section content
| '[' section
;
section
: SETTINGS NEWLINE settings_content
| TABLES NEWLINE tables_content
| RELATIONSHIPS NEWLINE relationships_content
;
settings_content
: settings_line NEWLINE settings_content
| settings_line NEWLINE
| settings_line
;
settings_line
: text '=' text
{ yy.regions.settings[$1] = $3; }
;
tables_content
: tables_line NEWLINE tables_content
| tables_line NEWLINE
| tables_line
;
tables_line
: table_name
{ yy.regions.tables.push({ name: $table_name, fields: [] }); }
| field_list
{
var tableCount = yy.regions.tables.length;
var tableIndex = tableCount - 1;
yy.regions.tables[tableIndex].fields.push($field_list);
}
;
table_name
: '-' text
{ $$ = $text; }
;
field_list
: text
{ $$=[]; $$.push($text); }
| field_list ',' text
{ $field_list.push($text); $$ = $field_list; }
;
relationships_content
: relationships_line NEWLINE relationships_content
| relationships_line NEWLINE
| relationships_line
;
relationships_line
: relationship_key '=>' relationship_key
{
yy.regions.relationships.push({
pkTable: $1,
fkTable: $3
});
}
| relationship_key '<=' relationship_key
{
yy.regions.relationships.push({
pkTable: $3,
fkTable: $1
});
}
;
relationship_key
: text '.' text
{ $$ = { name: $1, field: $3 }; }
| text
{ $$ = { name: $1 }; }
;
text
: TEXT
{ $$ = $TEXT; }
;
It's used to parse this kind of code:
[settings]
DefaultFieldType = string
[tables]
-table1
id, int, PK
username, string, NULL
password, string
-table2
id, int, PK
itemName, string
itemCount, int
[relationships]
table1 => table2
foo.test => bar.test2
Into this kind of JSON:
{ settings: { DefaultFieldType: 'string' },
tables:
[ { name: 'table1', fields: [Object] },
{ name: 'table2', fields: [Object] } ],
relationships:
[ { pkTable: [Object], fkTable: [Object] },
{ pkTable: [Object], fkTable: [Object] } ] }
However I don't get syntax error. When I go to Jison demo and try to parse 5*PI 3^2, I get the following error:
Parse error on line 1:
5*PI 3^2
-----^
Expecting 'EOF', '+', '-', '*', '/', '^', ')', got 'NUMBER'
which is expected. But when I change the last line of the code which I wish to parse from:
foo.test => bar.test2
to something like
foo.test => a bar.test2
I get the following error:
throw new _parseError(str, hash);
^
TypeError: Function.prototype.toString is not generic
I traced this to the generated parser code which looks like this:
if (hash.recoverable) {
this.trace(str);
} else {
function _parseError (msg, hash) {
this.message = msg;
this.hash = hash;
}
_parseError.prototype = Error;
throw new _parseError(str, hash);
}
So this leads me to believe that there is something wrong in how I structured my code and how I handled parsing but I have no idea what that might be.
It seems like it might have something to do with error recovery. If that is correct, how is that supposed to be used? Am I supposed to add the 'error' rule upwards to every element all the way to the source root?
Your grammar seems to work as expected in the Jison demo page, at least with the browser I'm using (Firefox 46.0.1). From the amount of activity in the git repository around the code that you cite, I suspect that the version of jison you are using has one of the bugs:
https://github.com/zaach/jison/issues/328
https://github.com/zaach/jison/issues/318
I think the jison version on the demo page is older, not newer, so if grabbing the current code from github doesn't work, you could try using an older version.