gocc
gocc copied to clipboard
Make typeMap/idMap publicly accessible
Curious.
Any good reason against making typeMap and idMap public, so its contents can be accessed by the consumer?
I've spent the past 6 hours trying to painfully retrieve a Type
's index from idMap
through reflection, and I'm still not close to a solution.
If it was IdMap
instead, one could simply loop over it and retrieve the index like so:
for i, k := range token.TokMap.IdMap {
switch k {
case intLit.Type:
fmt.Println(i)
}
}
What do you want to use it for?
On Tue, 2 Jul 2019 at 07:29, Happy-Ferret [email protected] wrote:
Curious.
Any good reason against making typeMap https://github.com/goccmack/gocc/blob/master/internal/token/gen/golang/token.go#L90 and idMap public, so its contents can be accessed by the consumer?
I've spent the past 6 hours trying to painfully retrieve a Type's index from idMap through reflection, and I'm still not close to a solution.
If it was IdMap instead, one could simply loop over it and retrieve the index like so:
for i, k := range token.TokMap.IdMap { switch k { case intLit.Type: fmt.Println(i) } }
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/goccmack/gocc/issues/92?email_source=notifications&email_token=AAN6YLL4ZKIUNPCCNWRHRNTP5LYTNA5CNFSM4H4YOEHKYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4G4ZQFPA, or mute the thread https://github.com/notifications/unsubscribe-auth/AAN6YLPX2ZBVPX7CKWILRW3P5LYTNANCNFSM4H4YOEHA .
NVM. After some head scratching it turned out to be much easier than I had thought.
t := reflect.ValueOf(token.TokMap)
v := t.FieldByName("typeMap").Index(int(intLit.Type))
// Prints integer type
println(v)
I'm in the process of writing a small language compiler and needed that information for the debug output.
Here's the full -- quick and dirty. I'm, obviously, going to make it generic for types other than int32 -- implementation of catching an overflow (message
is my own package for outputting compiler errors. I didn't like the verbose output of the gocc generated errors
package):
func NewIntegerLiteral(integer Attrib) (Expression, error) {
intLit, ok := integer.(*token.Token)
if !ok {
return nil, Error("NewIntegerLiteral", "*token.Token", "integer", integer)
}
maxInt := 0x7fffffff
minInt := -0x80000000
number, _ := strconv.Atoi(string(intLit.Lit))
if number > maxInt || number < minInt {
t := reflect.ValueOf(token.TokMap)
v := t.FieldByName("typeMap").Index(int(intLit.Type))
message.Errorf("Arithmetic overflow detected! %v overflows %v (Line: %v, Column: %v)", number, v, intLit.Pos.Line, intLit.Pos.Column)
}
return &IntegerLiteral{Token: intLit, Value: string(intLit.Lit)}, nil
}
Very interesting.
Why print out the error, instead of returning it?
Warning: I don’t know if FieldByName works for private fields for all versions of Go.
On Tue, 2 Jul 2019 at 08:30, Happy-Ferret [email protected] wrote:
NVM. After some head scratching it turned out to be much easier than I had thought.
t := reflect.ValueOf(token.TokMap)v := t.FieldByName("typeMap").Index(int(intLit.Type)) // Prints integer typeprintln(v)
I'm in the process of writing a small language compiler and needed that information for the debug output.
Here's the full -- quick and dirty. I'm, obviously, going to make it generic for types other than int32 -- implementation of catching an overflow (message is my own package for outputting compiler errors. I didn't like the verbose output of the gocc generated errors package):
func NewIntegerLiteral(integer Attrib) (Expression, error) { intLit, ok := integer.(*token.Token) if !ok { return nil, Error("NewIntegerLiteral", "*token.Token", "integer", integer) }
maxInt := 0x7fffffff minInt := -0x80000000 number, _ := strconv.Atoi(string(intLit.Lit))
if number > maxInt || number < minInt { t := reflect.ValueOf(token.TokMap) v := t.FieldByName("typeMap").Index(int(intLit.Type))
message.Errorf("Arithmetic overflow detected! %v overflows %v (Line: %v, Column: %v)", number, v, intLit.Pos.Line, intLit.Pos.Column)
}
return &IntegerLiteral{Token: intLit, Value: string(intLit.Lit)}, nil }
— You are receiving this because you commented.
Reply to this email directly, view it on GitHub https://github.com/goccmack/gocc/issues/92?email_source=notifications&email_token=AAN6YLMZHPIPFJSYBERI64LP5L7Z7A5CNFSM4H4YOEHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZALFOI#issuecomment-507556537, or mute the thread https://github.com/notifications/unsubscribe-auth/AAN6YLPPCR4ZW4L6LEPQ4ZLP5L7Z7ANCNFSM4H4YOEHA .
Why print out the error, instead of returning it?
Admittedly, because this project makes me feel like an utter newbie.
If I simply return the error with fmt.Errorf
, the output is formatted to:
ERROR Error in S21: sub(15,-), Pos(offset=284, line=14, column=21): Arithmetic overflow detected! -2147483649 overflows int (Line: 14, Column: 9)
So my message package looks like this instead:
package message
import (
"fmt"
"os"
colorable "github.com/mattn/go-colorable"
"github.com/sirupsen/logrus"
)
func init() {
timestampFormat := "Mon Jan 2 15:04:05 -0700 MST 2006"
var disableTimestamp bool
if len(os.Getenv("TCTimestamp")) == 1 {
disableTimestamp = false
} else {
disableTimestamp = true
}
logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true, DisableLevelTruncation: true, DisableTimestamp: disableTimestamp, FullTimestamp: true, TimestampFormat: timestampFormat})
logrus.SetOutput(colorable.NewColorableStdout())
}
// Error throws an error and aborts the running process.
func Error(v interface{}) {
logrus.Error(v)
os.Exit(1)
}
// Errorf formats an error message according to a format specifier,
// throws the error and aborts the running process.
func Errorf(format string, v ...interface{}) {
logrus.Error(fmt.Sprintf(format, v...))
os.Exit(1)
}
// Warning displays a warning log message.
func Warning(v interface{}) {
logrus.Warning(v)
}
// Info displays an informational log message.
func Info(v interface{}) {
logrus.Info(v)
}
You can still return the error log it after parsing, instead of logging it at the moment of the failure.