func ParseEval(env Env, input string, readLine func() string, sourceName string) (ast.Node, error) { defer func() { // Some non-application triggered panic has occurred if e := recover(); e != nil { fmt.Printf("Host environment error: %v\n", e) panic(e) } }() nodes, parseErrors := parser.Parse(input, sourceName) if parseErrors != nil { fmt.Println(parseErrors.String()) } var result ast.Node var evalError error for _, n := range nodes { result, evalError = Eval(env, n, os.Stdout, readLine) if evalError != nil { break } } if evalError == nil { return result, nil } else { return nil, evalError } }
func testInputFile(sourceFilePath string, t *testing.T) { sourceDirPart, sourceFileNamePart := filepath.Split(sourceFilePath) parts := strings.Split(sourceFileNamePart, ".") testName := parts[0] outputFilePath := sourceDirPart + testName + ".out" input, errIn := util.ReadFile(sourceFilePath) if errIn != nil { t.Errorf("Error reading file <" + sourceFilePath + ">: " + errIn.Error()) return } expectedRaw, errOut := util.ReadFile(outputFilePath) if errOut != nil { t.Errorf("Error reading file <" + outputFilePath + ">: " + errOut.Error()) return } // Remove any carriage return line endings from .out file expectedWithUntrimmed := strings.Replace(expectedRaw, "\r", "", -1) expected := strings.TrimSpace(expectedWithUntrimmed) nodes, errors := parser.Parse(input, sourceFilePath) if errors.Len() != 0 { verify(t, sourceFilePath, input, expected, errors.String()) } else { e := interpreter.NewTopLevelMapEnv() var outputBuffer bytes.Buffer dummyReadLine := func() string { return "text from dummy read line" } var result ast.Node var evalError error for _, n := range nodes { result, evalError = interpreter.Eval(e, n, &outputBuffer, dummyReadLine) if evalError != nil { break } } actual := (&outputBuffer).String() if evalError == nil { //DEBUG fmt.Printf("RESULT(%v): %v\n", sourceFilePath, result) if result != nil { actual = actual + result.String() } } else { actual = actual + evalError.Error() } verify(t, sourceFilePath, input, expected, actual) } }
func primReadString(e Env, head ast.Node, args []ast.Node) ast.Node { arg := args[0] switch val := arg.(type) { case *ast.Str: nodes, parseErrors := parser.Parse(val.Value, "string") if parseErrors != nil { panicEvalError(arg, fmt.Sprintf("Unable to read string %v: %v", val, parseErrors)) return nil } if len(nodes) == 0 { return &ast.Nil{} } return nodes[0] } panicEvalError(arg, "Argument to 'read-string' not a string: "+arg.String()) return nil }