Exemple #1
0
 protected override object?Visit(Expression.Proc proc)
 {
     symbolTable.PushScope(ScopeKind.Proc);
     base.Visit(proc);
     symbolTable.PopScope();
     return(null);
 }
Exemple #2
0
 protected override object?Visit(Expression.Proc proc)
 {
     Visit(proc.Signature);
     // NOTE: Parameters are already declared
     Visit(proc.Body);
     return(null);
 }
Exemple #3
0
 protected override Node?Visit(Expression.Proc proc)
 {
     if (dependencyMap.ProcDesugar.TryGetValue(proc, out var alt))
     {
         return(Transform(alt));
     }
     return(base.Visit(proc));
 }
Exemple #4
0
 protected override Value?Visit(Expression.Proc proc)
 {
     // It it's cached, just return that
     if (compiledProcs.TryGetValue(proc, out var procVal))
     {
         return(procVal);
     }
     WithSubcontext(() =>
     {
         procVal = Builder.DefineProc(nameContext.NameOf(proc));
         // Add it to the cache here to get ready for recursion
         compiledProcs.Add(proc, procVal);
         // For now we make every procedure public
         procVal.Visibility = Visibility.Public;
         // We need the return type
         Debug.Assert(proc.Signature.Return != null);
         var returnType = EvaluateType(proc.Signature.Return);
         procVal.Return = TranslateToLirType(returnType);
         // We need to compile parameters
         foreach (var param in proc.Signature.Parameters)
         {
             // Get the parameter type, define it in the Lir code
             var paramType    = EvaluateType(param.Type);
             var lirParamType = TranslateToLirType(paramType);
             var paramValue   = Builder.DefineParameter(lirParamType);
             // We make parameters mutable by making them allocate space on the stack and refer to that space
             var paramSpace = Builder.Alloc(lirParamType);
             // Copy the initial value
             Builder.Store(paramSpace, paramValue);
             if (param.Name != null)
             {
                 // It has a symbol, we store the allocated space associated
                 var symbol = SymbolTable.DefinedSymbol(param);
                 context.Variables.Add(symbol, paramSpace);
             }
         }
         // Now we can compile the body
         Visit(proc.Body);
         // Add a return, if there's none and the return-type is unit
         if (!Builder.CurrentBasicBlock.EndsInBranch && returnType.Equals(Semantic.Types.Type.Unit))
         {
             Builder.Ret();
         }
     });
     Debug.Assert(procVal != null);
     return(procVal);
 }
Exemple #5
0
        protected override object?Visit(Expression.Proc proc)
        {
            Visit(proc.Signature);
            // Evaluate parameter types, assign their return types
            foreach (var param in proc.Signature.Parameters)
            {
                var symbol = (Symbol.Var)System.SymbolTable.DefinedSymbol(param);
                symbol.Type = System.EvaluateType(param.Type);
            }
            // Deduce return type
            Debug.Assert(proc.Signature.Return != null);
            var returnType = System.EvaluateType(proc.Signature.Return);

            // We type-check with this return type
            WithCurrentProcReturnType(returnType, proc.Signature, () => Visit(proc.Body));
            return(null);
        }
Exemple #6
0
 protected override Node?Visit(Expression.Proc proc) =>
 new Expression.Proc(
     proc.ParseTreeNode,
     (Expression.ProcSignature)Transform(proc.Signature),
     DesugarProcBody(proc.Body));
Exemple #7
0
        protected override object?Visit(Expression.Proc proc)
        {
            base.Visit(proc);

            var procType   = (Type.Proc)System.TypeOf(proc);
            var dependency = procType.GetDependency();

            if (dependency != null)
            {
                /*
                 * Desugar
                 *  proc(dependee args..., dependent args..., independent args...) -> Ret {
                 *      body
                 *  }
                 * Into
                 *  proc(dependee args...) -> type {
                 *      struct {
                 *          const f = proc(dependent args..., independent args...) -> Ret {
                 *              body
                 *          };
                 *      }
                 *  }
                 */

                var result = new Expression.Proc(
                    null,
                    new Expression.ProcSignature(
                        null,
                        dependency.DependeeIndices
                        .Select(i => proc.Signature.Parameters[i])
                        .ToArray(),
                        new Expression.Identifier(null, "type")),
                    new Expression.Block(
                        null,
                        new Statement[] { },
                        new Expression.StructType(
                            null,
                            new Syntax.Token(new Text.Span(), Syntax.TokenType.KwStruct, "struct"),
                            new Expression.StructType.Field[] { },
                            new Statement[]
                {
                    new Declaration.Const(
                        null,
                        "f",
                        null,
                        new Expression.Proc(
                            null,
                            new Expression.ProcSignature(
                                null,
                                dependency.DependentIndices
                                .Concat(dependency.IndependentIndices)
                                .Select(i => proc.Signature.Parameters[i])
                                .ToArray(),
                                proc.Signature.Return),
                            proc.Body))
                })));
                result = (Expression.Proc) new Desugaring().Desugar(result);

                DependencyMap.ProcDesugar.Add(proc, result);
            }
            return(null);
        }