Example #1
0
 void AccessExpr(out ElaExpression exp)
 {
     Literal(out exp);
     while (la.kind == 27) {
     Get();
     if (la.kind == 54) {
         Get();
         if (la.kind == 1) {
             Get();
         } else if (la.kind == 2) {
             Get();
         } else if (StartOf(20)) {
             Operators();
         } else SynErr(92);
         exp = new ElaFieldReference(t) { FieldName = t.val, TargetObject = exp };
         Expect(55);
     } else if (la.kind == 1 || la.kind == 2) {
         if (la.kind == 1) {
             Get();
         } else {
             Get();
         }
         exp = new ElaFieldReference(t) { FieldName = t.val, TargetObject = exp };
     } else SynErr(93);
     }
 }
Example #2
0
        //Checks if a field reference is actually an exported name prefixed by a module
        //and if so emits a direct Pushexit op typeId. If this is not the case returns false
        //and the typeId gets compiled as a regular field reference.
        private bool TryOptimizeFieldReference(ElaFieldReference p)
        {
            if (p.TargetObject.Type != ElaNodeType.NameReference)
                return false;

            var mod = default(ModuleReference);
            var sv = GetVariable(p.TargetObject.GetName(), p.TargetObject.Line, p.TargetObject.Column);

            //Looks like a target object is not a module
            if ((sv.Flags & ElaVariableFlags.Module) != ElaVariableFlags.Module ||
                !frame.References.TryGetValue(p.TargetObject.GetName(), out mod))
                return false;

            var fieldSv = default(ScopeVar);

            //We have such a reference but looks like it couldn't be obtained
            //We don't need to handle this situation here, it is already reported by a linker
            if (refs[mod.LogicalHandle] == null)
                return false;

            //No such name, now captured statically
            if (!refs[mod.LogicalHandle].GlobalScope.Locals.TryGetValue(p.FieldName, out fieldSv) &&
                !options.IgnoreUndefined)
            {
                AddError(ElaCompilerError.UndefinedNameInModule, p, p.TargetObject.GetName(), p.FieldName);
                return false;
            }

            //Name is private, now captured statically
            if ((fieldSv.VariableFlags & ElaVariableFlags.Private) == ElaVariableFlags.Private)
            {
                AddError(ElaCompilerError.PrivateNameInModule, p, p.FieldName, p.TargetObject.GetName());
                return false;
            }

            AddLinePragma(p);
            cw.Emit(Op.Pushext, mod.LogicalHandle | fieldSv.Address << 8);
            return true;
        }