Retrieving variable name in order to print them in specman - specman

I wish to do the following in Specman:
my_task() is {
var my_var : int;
my_var = 5;
message(LOW,appendf("%s=[%d]",my_var.to_name(),my_var));
};
Currently, I'm in search of the internal task to_name(). I do not want to create a struct for this. I wish to only use Specman internals.

I'm not sure how you'd do this unless you somehow have the collection of all the fields, which would give you the name of all the fields.
So, I'm going to branch predict and assume that you want all the fields of a given struct/unit:
extend sys {
A : list of uint;
B : int;
cee : string;
run() is also {
var rf_sys: rf_struct = rf_manager.get_exact_subtype_of_instance(sys);
for each (field) in rf_sys.get_declared_fields() {
print field;
print field.get_long_name(); // <-- Here's your "get_name()" function
};
};
};
On version 8.2, this yields:
Usage: . env.sh [-32bit|-64bit] [-v] [[VAR=value]...]
Welcome to Specman Elite(64) (09.20.482-d) - Linked on Wed Mar 2 13:32:19
2011
Protected by U.S. Patents 6,141,630 ;6,182,258; 6,219,809; 6,347,388;
6,487,704; 6,499,132; 6,502,232; 6,519,727; 6,530,054; 6,675,138; 6,684,359;
6,687,662; 6,907,599; 6,918,076; 6,920,583; Other Patents Pending.
1 notification was modified by command 'set notify -severity=WARNING
DEPR_START_TCM_ARG_BY_REF'
Checking license ... OK
Loading /nfs/pdx/home/rbroger1/tmp.e ...
read...parse...update...patch...h code...code...clean...GC(sys)...
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
field = rf_field 'time', Specman's private modules
field.get_long_name() = "time"
field = rf_field 'logger', Specman's private modules
field.get_long_name() = "logger"
field = rf_field 'A', line 5 in #tmp
field.get_long_name() = "A"
field = rf_field 'B', line 6 in #tmp
field.get_long_name() = "B"
field = rf_field 'cee', line 7 in #tmp
field.get_long_name() = "cee"
No actual running requested.
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.
If that doesn't quite answer your question, look more into Specman's introspection or reflection interface in the documentation for your version of Specman. Warning, details are a bit scarce from Cadence. Also, see my answer to "Specman: how to retrieve values of var which is stored in another var".. Finally, in specview you can use the data browser to browse the rf_manger itself ( introspection at its best). Then you can find all the functions that Cadence doesn't tell you about in their documentation.

You can't get the string name of a variable. Although you can get the name of a field using get_name().
This makes some sense, because the variable is only known at the location it is declared. You can't even access the variable in a later extension of my_task(). So if you are already editing the code at the location where the variable was declared, just say "my_var" rather than my_var.to_name(). (Yes, typos and cut and paste errors can happen.)

I think this is what you are looking for:
define <dump'action> "dump <exp>" as {
out("<exp>","=[",<exp>,"]");
};
you can use this macro in the specman command line or inside functions, for example:
foo() is {
var a : int = 5;
dump a;
};
will give:
a=[5]

Related

Current year with 4 digits in elm 0.19.1

How can I do a function to get the current year with 4 digits using ELM 0.19.1? I have read something but nothing works with 0.19.1.
Signature:
getCurrentYear : Int
Execution:
getCurrentYear => 2020
Edit:
Maybe executing new Date().getFullYear() javascript code?
The simplest way would be to pass the year in via flags when you start the app, since the current year isn't likely to change in the course of the application running. In that case, you can use the snippet of JavaScript you suggested (ellie example):
Elm.Main.init({
node: document.querySelector('main'),
flags: {
year: new Date().getFullYear(),
}
});
module Main exposing (main)
import Browser
import Html exposing (Html, p, text)
type alias Flags =
{ year : Int }
main : Program Flags Model Msg
main =
Browser.element
{ init = \flags -> ( Model flags.year, Cmd.none )
, view = view
, update = update
, subscriptions = \_ -> Sub.none
}
type alias Model =
{ year : Int }
type Msg
= NoOp
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NoOp ->
( model, Cmd.none )
view : Model -> Html Msg
view model =
p [] [ text "The year is ", text (String.fromInt model.year) ]
Alternatively, you can use Time.now to request the current time, as Robin Zigmond's answer suggests, however that is pointing to Elm 0.18 documentation (for elm-lang/core instead of elm/time). For 0.19, you need both a Time.Posix and a Time.Zone in order to call Time.toYear. You can chain Time.now (a Task producing a Posix value) and Time.here (a Task producing a Zone with the current time zone offset) to retrieve those values in one Cmd. Here's an example (also on ellie)
module Main exposing (main)
import Browser
import Html exposing (Html, p, text)
import Task exposing (Task)
import Time
type alias Flags =
{ year : Int }
main : Program () Model Msg
main =
Browser.element
{ init = \() -> ( Model 0, whatYearIsIt |> Task.perform GotYear )
, view = view
, update = update
, subscriptions = \_ -> Sub.none
}
whatYearIsIt : Task x Int
whatYearIsIt =
Task.map2 Time.toYear Time.here Time.now
type alias Model =
{ year : Int }
type Msg
= GotYear Int
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
GotYear year ->
( { model | year = year }, Cmd.none )
view : Model -> Html Msg
view model =
p [] [ text "The year is ", text (String.fromInt model.year) ]
As I already said in my comment, it's impossible to define a function in Elm that returns the current year. You have to get such information from the Elm runtime system (which is basically JavaScript, but you don't have to write it yourself). This happens via commands, where you tell the runtime system to do something for you. But note that you can't simply retrieve the "return value" of that command and get it back into your Elm code. Instead you have to pass it into a function that can convert it into a "message" (see basic Elm Architecture tutorial here, it's fundamental to understand this before you can do anything with Elm) - this then allows you to store the value in your Model and thereby display it in your app.
These patterns do take some getting your head around, especially if you're not used to pure functional programming - but once you get used to it the benefits are huge, including a near guaranteed absence of runtime errors, and greatly enhanced ability to reason about your code.
For getting the year specifically, it looks like you need this library, which gives you (as now) a Task rather than a Cmd. You can use Task.perform to convert it to a command, which is documented here - in fact it even gives an example that matches your use case quite closely - I'll copy it here for posterity:
import Time -- elm install elm/time
import Task
type Msg
= Click
| Search String
| NewTime Time.Posix
getNewTime : Cmd Msg
getNewTime =
Task.perform NewTime Time.now
You'll have to fill this in to fit your own use case, in particular your own Msg type. But it gives a good basic outline. To get the user's current year, you need to replace the Time.Posix type with Int, and the Time.now command with (Task.map2 Time.toYear Time.here Time.now), as explained by #bdukes in his answer.

How can I get the name of procedure in Nim?

I am trying to write a macro for debug print in the Nim language.
Currently this macro adds filename andline to the output by instantiationInfo().
import macros
macro debugPrint(msg: untyped): typed =
result = quote do:
let pos = instantiationInfo()
echo pos.filename, ":", pos.line, ": ", `msg`
proc hello() =
debugPrint "foo bar"
hello()
currently output:
debug_print.nim:9: foo bar
I would like to add the name of the procedure (or iterator) of the place where the macro was called.
desired output:
debug_print.nim:9(proc hello): foo bar
How can I get the name of procedure (or iterator) in Nim, like __func__ in C?
At runtime you can do getFrame().procname, but it only works with stacktrace enabled (not in release builds).
At compile-time surprisingly I can't find a way to do it. There is callsite() in macros module, but it doesn't go far enough. It sounds like something that might fit into the macros.LineInfo object.
A hacky solution would be to also use __func__ and parse that back into the Nim proc name:
template procName: string =
var name: cstring
{.emit: "`name` = __func__;".}
($name).rsplit('_', 1)[0]
building on answer from #def- but making it more robust to handle edge cases of functions containing underscores, and hashes containing trailing _N or not
also using more unique names as otherwise macro would fail if proc defines a variable name
import strutils
proc procNameAux*(name:cstring): string =
let temp=($name).rsplit('_', 2)
#CHECKME: IMPROVE; the magic '4' chosen to be enough for most cases
# EG: bar_baz_9c8JPzPvtM9azO6OB23bjc3Q_3
if temp.len>=3 and temp[2].len < 4:
($name).rsplit('_', 2)[0]
else:
# EG: foo_9c8JPzPvtM9azO6OB23bjc3Q
($name).rsplit('_', 1)[0]
template procName*: string =
var name2: cstring
{.emit: "`name2` = __func__;".}
procNameAux(name2)
proc foo_bar()=
echo procName # prints foo_bar
foo_bar()
NOTE: this still has some issues that trigger in complex edge cases, see https://github.com/nim-lang/Nim/issues/8212

[zetapush]Error in macro: code=SUB_ASSIGN - Message = Assignment failed

When calling a macro I have the following error in response:
code=SUB_ASSIGN
Message = Assignment failed
Location= Reduce at line 65 of file mymacro.zms
the line 65 is
/** Reduce */
var b = gda(GDA).reduce {
table: 'myTable',
start: __parameters.key + '##',
stop: __parameters.key + '##a',
page: {
pageNumber: 0,
pageSize: 100000000
},
initialValue: {
tR: tR,
count: 0
},
'columns': ['col1', 'col2'],
'function': usr:myfunc
};
Seen on Android SDK (not on JS SDK) and not 100% reproducible.
What's the meaning of this error and how can I correct it?
Thanks.
The (poorly documented) meaning of SUB_ASSIGN is that an assignment with a syntax like a.b.c = d; has failed.
More precisely, the left hand operand is made of several hierarchical sub-parts (in my example a, b, and c).
Note that SUB_ASSIGN reports a programming error, which you should guard against :
when assigning a.b.c, at least a.b must exist and be not null.
A code pattern such as this one should do the trick:
// the ?? operator returns true when an expression is defined and not null
if (! a.b ??) {
a.b = {};
}
...
a.b.c = 0;
or, shorter, if applicable :
if (! a.b ??) {
a.b = {c:0};
}
The relevant documentation for '??' can be found in the official API reference documentation
As your code does not include such a statement anyway, I suppose that the actual error does not lie in your reduce call, but inside your callback function (usr:myfunc).
Moreover, to ease further debugging :
the error report you gave does not seem to contain the full stack trace up to the callback of the 'reduce' call. This might very well be a missing/not-yet-implemented feature of the zetapush API (which you could request...).

Swift: Indirect access / mutable

I need to go to a referenced structure:
class SearchKnot {
var isWord : Bool = false
var text : String = ""
var toNext = Dictionary<String,SearchKnot>()
}
When inserting, I need to update values in toNext dictionary. Because I want to avoid recursion, I do it in a loop. But there I need a variable which jumps from one toNext item to the other, able to change it.
var knots = toNext
...
let newKnot = SearchKnot()
knots[s] = newKnot
The last command only changes a local copy, but I need the original to be changed. I need an indirect access. In C I would use *p where I defined it as &toNext. But in Swift?
I found a solution. I remembered old pascal days. ;-)
I don't use the last reference, but the second last. Instead of
knots[s]
I use
p.knots[s]
For hopping to the next knot, I also use
p = p.knots[s]
and could use
p.knots[s]
again. Also p.knots[s] = newKnot works, because p is local not the entire term.

Test if property exists on a class at runtime

Something like this:
##class(MyApp.MyClass).%HasProperty("SomeProperty").
I looked into doing something like this:
set classDefinition = ##class(%Dictionary.CompiledClass).%OpenId(%class.Name)
and then looping through the Properties, however, I need to be able to use any class, not just %class
For a simple OO approach, you can use the following API:
Set tPropExists = ##class(%Dictionary.CompiledProperty).IDKEYExists("SomeClass","SomeProperty")
This should have much less runtime cost than loading the class definition data and looping over its properties (and thus loading the data for those properties as well).
If you still want to create a %HasProperty() helper method for your application classes, you can use the following base method (assuming you are on Cache 2010.2 or higher - I believe the $this special variable and the $classname() function were added in 2010.2, but that may have been in 2010.1.):
ClassMethod %HasProperty(pPropName As %String = "") As %Boolean
{
Set tHasProp = 0
If (pPropName '= "") {
Set tHasProp = ##class(%Dictionary.CompiledProperty).IDKEYExists($classname($this),pPropName)
}
Quit tHasProp
}
You also might want to use a generator method (one of the really nice features in Cache objects) if run-time speed is important to you.
For example:
Method PropertyExists(Name) As %Boolean [ CodeMode = generator, ProcedureBlock = 1, ServerOnly = 1 ]
{
Set %code=0
S ClassDef=##class(%Dictionary.CompiledClass).%OpenId(%class)
i '$IsObject(ClassDef) $$$GENERATE(" Q 0") Q $$$OK
I '$IsObject(ClassDef.Properties) $$$GENERATE(" Q 0") Q $$$OK
S Key="" F S Key=ClassDef.Properties.Next(Key) Q:Key="" D
. S CompiledProperty=ClassDef.Properties.GetAt(Key)
. $$$GENERATE(" I Name="""_CompiledProperty.Name_""" Q 1" )
$$$GENERATE(" Q 0")
q $$$OK
}