Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- func evalProgram(p *ast.Program) (string, error) {
- for _, function := range p.Functions {
- _, err := checker(function)
- if err != nil {
- return "", err
- }
- }
- for _, statement := range p.Statements {
- _, err := checker(statement)
- if err != nil {
- return "", err
- }
- }
- return "", nil
- }
- // Statements
- func evalBlockStatement(node *ast.BlockStatement) (string, error) {
- for _, statement := range node.Statements {
- result, err := checker(statement)
- if err != nil {
- return "", err
- }
- if reflect.TypeOf(statement) == reflect.TypeOf(&ast.ReturnStatement{}) {
- return result, nil
- }
- }
- return NOTHING_TYPE, nil
- }
- func evalReturnStatement(node *ast.ReturnStatement) (string, error) {
- res, err := checker(node.ReturnValue)
- return res, err
- }
- func evalIfStatement(node *ast.IfStatement) (string, error) {
- cond, _ := checker(node.Condition)
- if cond != BOOL_TYPE {
- return "", errors.New("condition not bool type")
- }
- checker(node.Block)
- checker(node.Alternative)
- return "", nil
- }
- func evalExpressionStatement(node *ast.ExpressionStatement) (string, error) {
- _, err := checker(node.Expression)
- if err != nil {
- return "", err
- }
- return "", nil
- }
- func evalInitStatement(node *ast.InitStatement) (string, error) {
- if env.IdentExist(node.Location) {
- return "", errors.New("ident already exist")
- }
- right, err := checker(node.Expr)
- if err != nil {
- return "", err
- }
- env.Set(node.Location, right) // set ident type
- return "", nil
- }
- func evalAssignStatement(node *ast.AssignStatement) (string, error) {
- right, err := checker(node.Right)
- if err != nil {
- return "", nil
- }
- if kind, ok := env.Get(node.Left.Value); ok {
- if kind != right {
- return "", errors.New("invalid type assignment")
- }
- } else {
- return "", errors.New("ident not exist")
- }
- return "", nil
- }
- func evalFunctionStatement(node *ast.FunctionStatement) (string, error) {
- var params []string
- for _, param := range node.Parameters {
- env.Set(param.Arg, param.Type) // set params into scope
- params = append(params, param.Type)
- }
- res, err := checker(node.Body)
- if err != nil {
- return "", err
- }
- // check if correct return type
- if res != node.Return {
- return "", errors.New("incorrect return type")
- }
- SetFunctionSignature(node.Name, Signature{node.Return, params})
- return "", nil
- }
Add Comment
Please, Sign In to add comment