Пример #1
0
        public void Accept(BinaryOperationNode node)
        {
            switch (node.BinaryOperation)
            {
            case BinaryOperation.Assignment:
                node.Right.Visit(this);
                // var = val
                if (node.Left is IdentifierNode)
                {
                    string identifier = ((IdentifierNode)node.Left).Identifier;

                    // Locals are lowercase
                    HassiumWarning.EnforceCasing(module, node.Left.SourceLocation, identifier, HassiumCasingType.Lower);

                    if (table.Scopes.Count == 2)
                    {
                        table.AddGlobalSymbol(identifier);
                    }

                    if (table.ContainsGlobalSymbol(identifier))
                    {
                        emit(node.SourceLocation, InstructionType.StoreGlobal, identifier);
                        emit(node.SourceLocation, InstructionType.LoadGlobal, identifier);
                    }
                    else
                    {
                        table.HandleSymbol(identifier);
                        emit(node.SourceLocation, InstructionType.StoreLocal, table.GetSymbol(identifier));
                        emit(node.SourceLocation, InstructionType.LoadLocal, table.GetSymbol(identifier));
                    }
                }
                // var.attrib = val
                else if (node.Left is AttributeAccessNode)
                {
                    AttributeAccessNode accessor = node.Left as AttributeAccessNode;
                    accessor.Left.Visit(this);
                    emit(node.SourceLocation, InstructionType.StoreAttribute, accessor.Right);
                    accessor.Left.Visit(this);
                }
                // var [index] = val
                else if (node.Left is IterableAccessNode)
                {
                    IterableAccessNode access = node.Left as IterableAccessNode;
                    access.Index.Visit(this);
                    access.Target.Visit(this);
                    emit(node.SourceLocation, InstructionType.StoreIterableElement);
                }
                break;

            case BinaryOperation.Swap:
                emit(node.SourceLocation, InstructionType.Push, table.GetSymbol(((IdentifierNode)node.Left).Identifier));
                emit(node.SourceLocation, InstructionType.Swap, table.GetSymbol(((IdentifierNode)node.Right).Identifier));
                break;

            default:
                node.VisitChildren(this);
                emit(node.SourceLocation, InstructionType.BinaryOperation, (int)node.BinaryOperation);
                break;
            }
        }
Пример #2
0
        public void Accept(ClassDeclarationNode node)
        {
            // Classes are PascalCase
            HassiumWarning.EnforceCasing(module, node.SourceLocation, node.Name, HassiumCasingType.Pascal);

            var clazz = new HassiumClass(node.Name);

            clazz.IsPrivate = node.IsPrivate;
            clazz.Parent    = classStack.Peek();
            clazz.DocStr    = node.DocStr;

            foreach (var inherit in node.Inherits)
            {
                methodStack.Push(new HassiumMethod(module)
                {
                    Parent = classStack.Peek()
                });
                inherit.Visit(this);
                emit(inherit.SourceLocation, InstructionType.Return);
                clazz.Inherits.Add(methodStack.Pop());
            }

            classStack.Push(clazz);
            table.EnterScope();

            node.Body.Visit(this);

            table.LeaveScope();
            classStack.Pop();
            classStack.Peek().AddAttribute(node.Name, clazz);
        }
Пример #3
0
        public void Accept(EnumNode node)
        {
            // Enums are PascalCase
            HassiumWarning.EnforceCasing(module, node.SourceLocation, node.Name, HassiumCasingType.Pascal);

            HassiumEnum enum_ = new HassiumEnum(node.Name);

            enum_.IsPrivate = node.IsPrivate;
            foreach (var pair in node.Attributes)
            {
                enum_.AddAttribute(pair.Value, new HassiumInt(pair.Key));
            }

            classStack.Peek().AddAttribute(enum_.Name, enum_);
        }
Пример #4
0
        public void Accept(TraitNode node)
        {
            // Traits are PascalCase
            HassiumWarning.EnforceCasing(module, node.SourceLocation, node.Name, HassiumCasingType.Pascal);

            HassiumTrait trait = new HassiumTrait(node.Name);

            trait.IsPrivate = node.IsPrivate;

            foreach (var pair in node.Attributes)
            {
                methodStack.Push(new HassiumMethod(module));
                pair.Value.Visit(this);
                emit(pair.Value.SourceLocation, InstructionType.Return);
                var type = methodStack.Pop();

                HassiumDictionary.DictTypeDef.add(null, trait.Traits, pair.Value.SourceLocation, new HassiumString(pair.Key), type);
            }

            classStack.Peek().AddAttribute(node.Name, trait);
        }
Пример #5
0
        public void Accept(FunctionDeclarationNode node)
        {
            // Funcs are lowercase
            HassiumWarning.EnforceCasing(module, node.SourceLocation, node.Name, HassiumCasingType.Lower);

            var method = new HassiumMethod(module, node.Name);

            method.DocStr    = node.DocStr;
            method.IsPrivate = node.IsPrivate;
            methodStack.Push(method);
            method.SourceLocation       = node.SourceLocation;
            method.SourceRepresentation = node.ToString();
            method.Parent = classStack.Peek();

            table.EnterScope();

            foreach (var param in node.Parameters)
            {
                if (param.FunctionParameterType == FunctionParameterType.Enforced)
                {
                    methodStack.Push(new HassiumMethod(module));
                    methodStack.Peek().Parent = classStack.Peek();
                    param.Type.Visit(this);
                    emit(param.Type.SourceLocation, InstructionType.Return);
                    param.EnforcedType = methodStack.Pop();
                }
                method.Parameters.Add(param, table.AddSymbol(param.Name));
            }

            if (node.Body is CodeBlockNode)
            {
                node.Body.VisitChildren(this);
            }
            else
            {
                node.Body.Visit(this);
            }

            if (node.EnforcedReturnType != null)
            {
                methodStack.Push(new HassiumMethod(module));
                node.EnforcedReturnType.Visit(this);
                emit(node.EnforcedReturnType.SourceLocation, InstructionType.Return);
                method.ReturnType = methodStack.Pop();
            }

            table.LeaveScope();
            method = methodStack.Pop();

            if (classStack.Peek().ContainsAttribute(method.Name))
            {
                var attrib = classStack.Peek().BoundAttributes[method.Name];
                if (attrib is HassiumMultiFunc)
                {
                    (attrib as HassiumMultiFunc).Methods.Add(method);
                }
                else
                {
                    classStack.Peek().BoundAttributes.Remove(method.Name);
                    var multiFunc = new HassiumMultiFunc();
                    multiFunc.Methods.Add(attrib as HassiumMethod);
                    multiFunc.Methods.Add(method);
                    classStack.Peek().AddAttribute(method.Name, multiFunc);
                }
            }
            else
            {
                classStack.Peek().AddAttribute(method.Name, method);
            }
        }