Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /branches/vis15/src/compiler/typechecker/env.sml
ViewVC logotype

View of /branches/vis15/src/compiler/typechecker/env.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3398 - (download) (annotate)
Wed Nov 11 01:17:58 2015 UTC (3 years, 10 months ago) by jhr
File size: 5191 byte(s)
working on merge
(* env.sml
 *
 * Environments and contexts to support typechecking.
 *
 * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
 *
 * COPYRIGHT (c) 2015 The University of Chicago
 * All rights reserved.
 *)

structure Env : sig

    datatype scope
      = GlobalScope				(* global declarations *)
      | FunctionScope of Ty.ty * Atom.atom	(* inside a function definition *)
      | StrandScope				(* inside a strand definition *)
      | MethodScope of StrandUtil.method_name	(* inside a strand method definition *)
      | InitScope				(* inside global initialization *)
      | CreateScope				(* inside initial strand creation *)
      | UpdateScope				(* inside global update *)

    val scopeToString : scope -> string

    type env

    type context = Error.err_stream * Error.span

  (* unwrap a parse-tree location marker and update the context with the span *)
    val withContext : context * 'a Error.mark -> (context * 'a)

  (* same as `withContext`, but includes the environment too *)
    val withEnvAndContext : env * context * 'a Error.mark -> (env * context * 'a)

  end = struct

    structure GE = GlobalEnv

    datatype scope
      = GlobalScope				(* global declarations *)
      | FunctionScope of Ty.ty * Atom.atom	(* inside a function definition *)
      | StrandScope				(* inside a strand definition *)
      | MethodScope of StrandUtil.method_name	(* inside a strand method definition *)
      | InitScope				(* inside global initialization *)
      | CreateScope				(* inside initial strand creation *)
      | UpdateScope				(* inside global update *)

    fun scopeToString GlobalScope = "global scope"
      | scopeToString (FunctionScope(_, f)) = "function " ^ Atom.toString f
      | scopeToString StrandScope = "strand initialization"
      | scopeToString (MethodScope m) = "method " ^ StrandUtil.nameToString m
      | scopeToString InitScope = "initialization"
      | scopeToString InitScope = "global initialization"
      | scopeToString CreateScope = "strand creation"
      | scopeToString UpdateScope = "global update"

    type env = {
        scope : scope,                          (* current scope *)
(* NOTE: since we added location info to variables, we probably don't need this anymore! *)
        bindings : Error.location AtomMap.map,  (* map from atoms to innermost binding location *)
        gEnv : global_env,			(* global environment *)
        vEnv : AST.var AMap.map			(* variables defined in inner scopes *)
      }

    type context = Error.err_stream * Error.span

  (* start a new scope *)
    fun functionScope ({scope, bindings, env}, ty, f) =
          {scope=FunctionScope(ty, f), bindings=AtomMap.empty, env=env}
    fun strandScope {scope, bindings, env} =
          {scope=StrandScope, bindings=AtomMap.empty, env=env}
    fun methodScope ({scope, bindings, env}, name) =
          {scope=MethodScope name, bindings=AtomMap.empty, env=env}
    fun initScope {scope, bindings, env} =
          {scope=InitScope, bindings=AtomMap.empty, env=env}
    fun blockScope {scope, bindings, env} =
          {scope=scope, bindings=AtomMap.empty, env=env}

    fun inMethod {scope=MethodScope _, bindings, env} = true
      | inMethod _ = false

    fun inStrand {scope=StrandScope, bindings, env} = true
      | inStrand {scope=MethodScope _, ...} = true
      | inStrand _ = false

    fun insertStrand ({scope, bindings, env}, cxt, s as AST.Strand{name, ...}) = {
            scope=scope,
            bindings = AtomMap.insert(bindings, name, Error.location cxt),
            env=Env.insertStrand(env, s)
          }
    fun insertFunc ({scope, bindings, env}, cxt, f, f') =  let
          val loc = Error.location cxt
          in
            setLoc(f', loc);
            {
              scope = scope,
              bindings = AtomMap.insert(bindings, f, loc),
              env = Env.insertFunc(env, f, Env.UserFun f')
            }
          end
    fun insertLocal ({scope, bindings, env}, cxt, x, x') = let
          val loc = Error.location cxt
          in
            setLoc(x', loc);
            {
              scope = scope,
              bindings = AtomMap.insert(bindings, x, loc),
              env = Env.insertLocal(env, x, x')
            }
          end
    fun insertGlobal ({scope, bindings, env}, cxt, x, x') = let
          val loc = Error.location cxt
          in
            setLoc(x', loc);
            {
              scope = scope,
              bindings = AtomMap.insert(bindings, x, loc),
              env = Env.insertGlobal(env, x, x')
            }
          end

    fun withContext ((errStrm, _), {span, tree}) =
          ((errStrm, span), tree)
    fun withEnvAndContext (env, (errStrm, _), {span, tree}) =
          (env, (errStrm, span), tree)

  (* check for redefinition of an identifier in the same scope *)
(* TODO: check for shadowing too? *)
    fun checkForRedef (env : env, cxt : context, x) = (case AtomMap.find(#bindings env, x)
           of SOME loc => err (cxt, [
                  S "redefinition of ", A x,
		  S(Error.fmt (", previous definition at line %l", "") loc)
                ])
            | NONE => ()
          (* end case *))

  end

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0