1/*
2 * gomacro - A Go interpreter with Lisp-like macros
3 *
4 * Copyright (C) 2017-2019 Massimiliano Ghilardi
5 *
6 *     This Source Code Form is subject to the terms of the Mozilla Public
7 *     License, v. 2.0. If a copy of the MPL was not distributed with this
8 *     file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 *
10 *
11 * type.go
12 *
13 *  Created on: Feb 19, 2017
14 *      Author: Massimiliano Ghilardi
15 */
16
17package base
18
19import (
20	"sort"
21	"strings"
22)
23
24type Options uint
25type WhichMacroExpand uint
26
27const (
28	OptCollectDeclarations Options = 1 << iota
29	OptCollectStatements
30	OptCtrlCEnterDebugger // Ctrl+C enters the debugger instead of injecting a panic. requires OptDebugger
31	OptDebugger           // enable debugger support. "break" and _ = "break" are breakpoints and enter the debugger
32	OptKeepUntyped
33	OptMacroExpandOnly // do not compile or execute code, only parse and macroexpand it
34	OptPanicStackTrace
35	OptTrapPanic
36	OptDebugCallStack
37	OptDebugDebugger // print debug information related to the debugger
38	OptDebugField
39	OptDebugFromReflect
40	OptDebugMacroExpand
41	OptDebugMethod
42	OptDebugParse
43	OptDebugRecover
44	OptDebugQuasiquote
45	OptDebugSleepOnSwitch // to torture-test "switch" implementation for race conditions
46	OptDebugTemplate
47	OptShowCompile
48	OptShowEval
49	OptShowEvalType
50	OptShowMacroExpand
51	OptShowParse
52	OptShowPrompt
53	OptShowTime
54)
55
56const (
57	CMacroExpand1 WhichMacroExpand = iota
58	CMacroExpand
59	CMacroExpandCodewalk
60)
61
62var optNames = map[Options]string{
63	OptCollectDeclarations: "Declarations.Collect",
64	OptCollectStatements:   "Statements.Collect",
65	OptCtrlCEnterDebugger:  "CtrlC.Debugger.Enter",
66	OptDebugger:            "Debugger",
67	OptKeepUntyped:         "Untyped.Keep",
68	OptMacroExpandOnly:     "MacroExpandOnly",
69	OptPanicStackTrace:     "StackTrace.OnPanic",
70	OptTrapPanic:           "Trap.Panic",
71	OptDebugCallStack:      "?CallStack.Debug",
72	OptDebugDebugger:       "?Debugger.Debug",
73	OptDebugField:          "?Field.Debug",
74	OptDebugFromReflect:    "?FromReflect.Debug",
75	OptDebugMacroExpand:    "?MacroExpand.Debug",
76	OptDebugMethod:         "?Method.Debug",
77	OptDebugParse:          "?Parse.Debug",
78	OptDebugRecover:        "?Recover.Debug",
79	OptDebugQuasiquote:     "?Quasiquote.Debug",
80	OptDebugSleepOnSwitch:  "?SwitchSleep.Debug",
81	OptDebugTemplate:       "?Template.Debug",
82	OptShowCompile:         "Compile.Show",
83	OptShowEval:            "Eval.Show",
84	OptShowEvalType:        "Type.Eval.Show",
85	OptShowMacroExpand:     "MacroExpand.Show",
86	OptShowParse:           "Parse.Show",
87	OptShowPrompt:          "Prompt.Show",
88	OptShowTime:            "Time.Show",
89}
90
91var optValues = map[string]Options{}
92
93func init() {
94	for k, v := range optNames {
95		optValues[v] = k
96	}
97}
98
99func (o Options) String() string {
100	names := make([]string, 0)
101	for k, v := range optNames {
102		if k&o != 0 {
103			names = append(names, v)
104		}
105	}
106	sort.Strings(names)
107	return strings.Join(names, " ")
108}
109
110func ParseOptions(str string) Options {
111	var opts Options
112	for _, name := range strings.Split(str, " ") {
113		if opt, ok := optValues[name]; ok {
114			opts ^= opt
115		} else if len(name) != 0 {
116			for k, v := range optNames {
117				if strings.HasPrefix(v, name) {
118					opts ^= k
119				}
120			}
121		}
122	}
123	return opts
124}
125
126func (m WhichMacroExpand) String() string {
127	switch m {
128	case CMacroExpand1:
129		return "MacroExpand1"
130	case CMacroExpandCodewalk:
131		return "MacroExpandCodewalk"
132	default:
133		return "MacroExpand"
134	}
135}
136