Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make typeMap/idMap publicly accessible #92

Open
Happy-Ferret opened this issue Jul 2, 2019 · 5 comments
Open

Make typeMap/idMap publicly accessible #92

Happy-Ferret opened this issue Jul 2, 2019 · 5 comments

Comments

@Happy-Ferret
Copy link

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)
		}
	}
@awalterschulze
Copy link
Collaborator

awalterschulze commented Jul 2, 2019 via email

@Happy-Ferret
Copy link
Author

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
}

@awalterschulze
Copy link
Collaborator

awalterschulze commented Jul 2, 2019 via email

@Happy-Ferret
Copy link
Author

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)
}

@awalterschulze
Copy link
Collaborator

You can still return the error log it after parsing, instead of logging it at the moment of the failure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants