Pre-compile textual replacement macro with arguments

143 Views Asked by At

I am trying to create some kind of a dut_error wrapper. Something that will take some arguments and construct them in a specific way to a dut_error.

I can't use a method to replace the calls to dut_error because to my understanding after check that ... then ... else can only come a dut_error (or dut_errorf). And indeed if I try to do something like:

my_dut_error(arg1: string, arg2: string) is {
    dut_error("first argument is ", arg, " and second argument is ", arg2);
};

check that FALSE else my_dut_error("check1", "check2");

I get an error:

*** Error: Unrecognized exp
 [Unrecognized expression 'FALSE else my_dut_error("check1", "check2")']
     at line x in main.e
         check that FALSE else my_dut_error("check1", "check2");
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

So I thought about defining a macro to simply do a textual replace from my wrapper to an actual dut_error:

define <my_dut_error'exp> "my_dut_error(<arg1'name>, <arg2'name>)" as {
    dut_error("first argument is ", <arg1'name>, " and second argument is ", <arg2'name>)
};

But got the same error.

Then I read about the preprocessor directive #define so tried:

#define my_dut_error(arg1, arg2) dut_error("first argument is ", arg, " and second argument is ", arg2)

But that just gave a syntax error.

How can I define a pre-compiled textual replacement macro that takes arguments, similar to C?


The reason I want to do that is to achieve some sort of an "interface" to the dut_error so all errors have a consistent structure. This way, different people writing different errors will only pass the arguments necessary by that interface and internally an appropriate message will be created.

3

There are 3 best solutions below

1
user3467290 On

not sure i understood what you want to do in the wrapper, but perhaps you can achieve what you want by using the dut_error_struct.

it has set of api, which you can use as hooks (do something when the error is caught) and to query about the specific error. for example:

extend dut_error_struct {
   pre_error() is also {
      if source_method_name() == "post_generate" and 
         source_struct() is a BLUE packet {
         out("\nProblem in generation? ", source_location());
         // do something for error during generation
    };
    write() is first {
       if get_mesage() ~ "AHB Error..." {
           ahb_monitor::increase_errors();
       };
    }; 
    
};
2
user3467290 On

dut_error accepts one parameter, one string. but you can decide of a "separator", that will define two parts to the message. e.g. - instruct people to write "XXX" in the message, before "first arg" and "second arg".

check that legal else dut_error("ONE thing", "XXX", "another thing");
check that x < 7 else dut_error("failure ", "XXX", "of x not 7 but is ", x);


extend dut_error_struct {
    write() is first {
        var message_parts := str_split(get_message(), "XXX");
    
    if message_parts.size() == 2 {
        out ("First part of message is ", message_parts[0],
             "\nand second part of message is ", message_parts[1]
            );
    };
};
0
Tomerikoo On

I could get pretty close to what I want using the dut_errorf method combined with a preprocessor directive defining the format string:

#define DUT_FORMAT "first argument is %s and second argument is %s"

check that FALSE else dut_errorf(DUT_FORMAT, "check1", "check2");

but I would still prefer a way that doesn't require this DUT_FORMAT directive and instead uses dut_error_struct or something similar.