AST parsing, detect current scope - scope

When parsing AST with visitor, how could visitor detect when scope changes? For example, when we are in Class node, we create Class scope, but how to detect when we leaving a class node, to close the scope?
1: Stmt_Class(
type: 0
extends: null
implements: array(
)
stmts: array(
0: Stmt_ClassMethod(
type: 1
byRef: false
params: array(
0: Param(
name: str
default: null
type: null
byRef: false
)
)
stmts: array(
0: Stmt_Return(
expr: Expr_FuncCall(
name: Name(
parts: array(
0: mysql_real_escape_string
)
name: null
)
args: array(
0: Arg(
value: Expr_Variable(
name: str
)
byRef: false
name: null
)
)
)
name: null
)
)
name: clear
)
)
name: Filter
)

Use a simple scope stack. When you enter a new scope, push a new scope representation to the stack, when you leave it - pop it.
The first scope on the stack would be pre-defined and hold things like language constants.
When looking up a reference iterate through the stack from top down.

Related

Select Menu Discord JS | How can i use array in .addOptions?

I would like to map an array inside .addOptions.
Basically, I would like to add a value { } to addOptions by taking the values of an object or array.
Examples:
let menu = new SelectMenuBuilder()
.setCustomId('select')
.setPlaceholder('Nothing selected')
.addOptions(arrayt.map(song => label: song.name, description: song.formattedDuration, value: blabla)
You are missing curly brackets in your map function. The function should look something like this
const songs = [
{
name: 'Song 1',
formattedDuration: 2
},
{
name: 'Song 2',
formattedDuration: 5
},
{
name: 'Song 3',
formattedDuration: 6
}
]
const menu = new SelectMenuBuilder()
.setCustomId('select')
.setPlaceholder('Nothing selected')
.addOptions(songs.map(song => { return {label: song.name, description: song.formattedDuration }}))
The values should be in the form of a string, not integer or double, whatever you are giving, use toString() on them.
const row = new ActionRowBuilder().addComponents(
new StringSelectMenuBuilder()
.setCustomId('select')
.setPlaceholder('Nothing selected')
.addOptions(
adana.map(function (curentValue, index) {
return {
label: index.toString(),
value: index.toString(),
}
})
)
)

get RealmResults in array instead of object in NodeJs

I have a simple Schema
const MediaElementSchema = {
primaryKey: 'id',
name: 'MediaElement',
properties: {
id: 'int',
type: 'string',
path: 'string'
}
}
When I try to get all:
let elements = realm.objects('MediaElement')
Realm returns the results in an object like below:
{"0": Record1, "1" : Record2, etc}
is there a way for realm to return an array of the elements like:
[Element1, Element2, etc]
I checked the documentation but didn't find anything relevant about the return type.
https://realm.io/docs/javascript/latest
You could just use plain old javascript to convert object into array.
let elements = {'0': 'Record1', '1' : 'Record2'};
elements = Object.keys(elements).map(key => elements[key]);
console.log(elements); // ["Record1", "Record2"]

Access Object property using key name within map

I have below array of object
const reports = [{id:3, name:'three', description:'three d', other: 'other 3'}, {id:2, name:'two', description:'two d', other: 'other 2'}];
and I want to filter out only 2 property of each object and below is my desired output
[{id:3, name:'three'}, {id:2, name:'two'}];
so tried this way
const reportList = reports.map((report) => {id,name} );
console.log(reportList);
throw error
ReferenceError: id is not defined
even I can achieve this by using this approach
this.reportList = reports.map((report) => ({
id: report.id,
name: report.name,
description: report.description
}));
but here I need to write extra code, I want to use object accessor using key, can I achieve anyway?
You must wrap the returning object literal into parentheses. Otherwise curly braces will be considered to denote the function’s body. The following works:
const reports = [{
id: 3,
name: 'three',
description: 'three d',
other: 'other 3'
}, {
id: 2,
name: 'two',
description: 'two d',
other: 'other 2'
}];
const reportList = reports.map(({id, name}) => ({
id,
name
}));
console.log(reportList);
Reference: Returning object literals by MDN

String parsing algorithm

Regular expressions are a good way to parse regular strings, but when the strings becomes more complex, the regex becomes n² times more complex.
What is the general approach to string parsing in general?
For example. I currently have defined a syntax ({who}[{where}].{what} = {value}) that can or cannot define certain components.
It's simple enough to be easily understood but complex enough to require a large regex.
Generally, the are some components that can be omitted, however, there are certain components that depends on other components. Example:
'key = value' => {
who: null,
where: null,
what: 'key',
value: 'value'
}
'me.key = value' => {
who: 'me',
where: null,
what: 'key',
value: 'value'
}
'me[here].key = value' => {
who: 'me',
where: 'here',
what: 'key',
value: 'value'
}
'me[here] = value' => 'Error! Need to specify *what*.'
'[here].key = value' => 'Error! Need to specify *who* if *where* is specified.'

Groovy method that takes multiple arguments of type Maps

i have a groovy method that works with hard coded variable of map containing maps. I would like to make, such that the maps are passed as arguments. The number of maps will vary as well. A simple representation that i am trying to achieve will be like so:
def name(Map p...) {
//code to loop through each of the maps
p.each { k ->
"${k.first}, ${k.last}"
//another loop with the internal map
something {
k.details.each { name, value ->
//some code
}
}
}
}
And example of the Map of maps that i would need to pass as Args looks like so:
def persons = [
[first: 'Jack', last: 'Smith', details: [gender: 'male', Age: 25]],
[first: 'Sean', last: 'Dean', details: [gender: 'male', Age: 26]]
]
Then down the line, i would like to call something like
name(persons)
how can i achieve this? My test so far in the groovyConsole isn't taking me anywhere...
I think the problem is, that you don't have a map of maps but a list of maps. So to be able to call your method with the persons as parameter you have to change its signature to:
def map(List p) {
...
}
This is my snippet in the groovyConsole:
def persons = [
[first: 'Jack', last: 'Smith', details: [gender: 'male', Age: 25]],
[first: 'Sean', last: 'Dean', details: [gender: 'male', Age: 26]]
]
class Person {
def name(List p) {
println p
}
}
def p = new Person()
p.name(persons)
The problem is that you're passing a list to varArgs, you have to use *(list) to extract each element out of the list and pass them:
Example:
def name( Map... p ) {
p.each{ println it}
}
def persons = [
[first: 'Jack', last: 'Smith', details: [gender: 'male', Age: 25]],
[first: 'Sean', last: 'Dean', details: [gender: 'male', Age: 26]]
]
name(*(persons))
Note: I am not quite sure I am using the right terminology but I hope you get the gist :)

Resources