Exemplo n.º 1
0
Arquivo: main.go Projeto: mhoc/msp
func main() {
	log.Trace("-m-", "Opening input file")

	// Parse debug flags
	flag.BoolVar(&log.LOG_TOKENS, "log-tokens", false, "Enable list of parsed tokens")
	flag.BoolVar(&log.LOG_TRACE, "log-trace", false, "Enable trace logging of debug output")
	flag.BoolVar(&log.EXTENSIONS, "extensions", false, "Enables parser extensions for additional features. See README for a list of these.")
	flag.Parse()

	// Init builtin functions
	ast.InitBuiltins()

	// Parse command line arguments
	var file *os.File
	var err error
	if flag.NArg() == 0 {
		log.Trace("-m-", "Reading from stdin")
		file = os.Stdin
	} else if flag.NArg() == 1 {
		log.Trace("-m-", "Reading from file "+flag.Arg(0))
		file, err = os.Open(flag.Arg(0))
	} else {
		panic("Must provide filename to read from or no filename at all")
	}

	if err != nil {
		panic("File name provided does not exist")
	}

	log.Trace("-m-", "Beginning lex")
	yyParse(NewLexer(file))

}
Exemplo n.º 2
0
// Declares a new variable in the current scope
func Declare(name string) {
	if Scope == nil {
		log.Trace("sym", "Declaring global variable "+name)
		GlobalScope[name] = Value{Type: VALUE_UNDEFINED, Written: false}
	} else {
		log.Trace("sym", "Declaring scope-local variable "+name)
		Scope[name] = Value{Type: VALUE_UNDEFINED, Written: false}
	}
}
Exemplo n.º 3
0
func (fd FunctionDef) Execute() interface{} {
	log.Trace("ast", "Defining function "+fd.Name)

	// Store this function in the symbol table
	value := Value{Type: VALUE_FUNCTION, Value: fd, Line: fd.Line, Written: true}
	Declare(fd.Name)
	AssignToVariable(fd.Name, value, fd.Line)
	return nil
}
Exemplo n.º 4
0
func (f FunctionCall) Execute() interface{} {
	log.Trace("ast", "Executing function "+f.Name)

	// Create the local stack and return val
	f.LocalScope = make(map[string]Value)
	f.ReturnVal = Value{Type: VALUE_UNDEFINED, Line: f.Line}
	// Retrieve the function definition
	funVal := GetVariable(f.Name, f.Line)
	if funVal.Type != VALUE_FUNCTION {
		log.TypeViolation(f.Line)
		return f.ReturnVal
	}
	funDef := funVal.Value.(FunctionDef)
	// Check number of arguments
	if !funDef.ArbitraryArgs && len(f.Args) != len(funDef.ArgNames) {
		log.TypeViolation(f.Line)
		return f.ReturnVal
	}
	if funDef.ExecMiniscript {
		// Load the arguments into the local stack
		for i, name := range funDef.ArgNames {
			f.LocalScope[name] = f.Args[i].Execute().(Value)
		}
		// Save the old scope and set this local as its own scope
		oldScope := Scope
		Scope = f.LocalScope
		// Execute the function
		retVal := funDef.MSBody.Execute()
		var nRetVal Value
		switch retVal.(type) {
		case Return:
			nRetVal = retVal.(Return).Value.Execute().(Value)
		case Value:
			nRetVal = retVal.(Value)
		}
		// Restore the old scope
		Scope = oldScope
		return nRetVal
	} else {
		funDef.GoBody(f)
		return nil
	}
}
Exemplo n.º 5
0
Arquivo: loops.go Projeto: mhoc/msp
func (l Loop) Execute() interface{} {
	log.Trace("ast", "Executing loop")

	condition := Value{Type: VALUE_BOOLEAN, Value: true}
	for {

		if l.PreCheck {
			condition = l.Conditional.Execute().(Value).ToBoolean()
			if condition.Type != VALUE_BOOLEAN {
				log.ConditionError(l.Line)
				return nil
			}
		}

		var breakMet = false
		if condition.Value.(bool) {
			LoopDepth++
			jump := l.Body.Execute()
			LoopDepth--
			switch jump.(type) {
			case Break:
				breakMet = true
			}
		} else {
			break
		}

		if breakMet {
			break
		}

		if !l.PreCheck {
			condition = l.Conditional.Execute().(Value).ToBoolean()
			if condition.Type != VALUE_BOOLEAN {
				log.ConditionError(l.Line)
				return nil
			}
		}

	}
	return nil

}