MATEUS KREPSKY LUDWICH ADAPTAÇÃO DA MÁQUINA VIRTUAL PYTHON PARA O SISTEMA OPERACIONAL EPOS Florianópolis – SC Fevereiro 2007 MATEUS KREPSKY LUDWICH ADAPTAÇÃO DA MÁQUINA VIRTUAL PYTHON PARA O SISTEMA OPERACIONAL EPOS Trabalho de Conclusão de Curso submetido à Universidade Federal de Santa Catarina como parte dos requisitos para a obtenção do grau de Bacharel em Ciências da Computação. Professor Dr. Antônio Augusto Medeiros Fröhich BACHARELADO EM C I ÊNCIAS DA C OMPUTAÇ ÃO D EPARTAMENTO DE I NFORM ÁTICA E E STAT ÍSCA C ENTRO T ECNOL ÓGICO U NIVERSIDADE F EDERAL DE S ANTA C ATARINA Florianópolis Junho 2007 Trabalho de Conclusão de Curso sob o tı́tulo “Adaptação da Máquina Virtual Python para o Sistema Operacional EPOS”, defendido por Mateus Krepsky Ludwich e aprovado em xx de zzz de 200x, em Florianópolis, Santa Catarina, pela banca examinadora constituı́da por: Prof. Dr. Antônio Augusto Medeiros Fröhich Departamento de Informática e Estatı́stica - INE Orientador Hugo Marcondes Departamento de Informática e Estatı́stica - INE Lucas Wanner Departamento de Informática e Estatı́stica - INE RESUMO O objetivo do projeto é permitir que o sistema operacional EPOS possa executar aplicações em byte code Python. Para tanto deverá ser estudada a máquina virtual Python de modo que ela possa ser adaptada para funcionar com os componentes do EPOS, que também será alvo de estudo. SUMÁRIO 1 INTRODUÇÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 6 2 OBJETIVOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 8 2.1 OBJETIVO GERAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 8 2.2 OBJETIVOS ESPECÍFICOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 8 3 REVISÃO TEÓRICA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 9 3.1 SISTEMAS EMBUTIDOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 9 3.2 SISTEMAS OPERACIONAIS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 10 3.2.1 CONCEITOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 10 3.2.2 EPOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 10 3.3 LINGUAGENS DE PROGRAMAÇÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 10 3.4 MÉTODOS DE IMPLEMENTAÇÃO DE LINGUAGENS DE PROGRAMAÇÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 11 3.4.1 COMPILAÇÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 12 3.4.2 INTERPRETAÇÃO PURA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 13 3.4.3 SISTEMAS DE IMPLEMENTAÇÃO HÍBRIDOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 13 3.5 PYTHON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 14 3.5.1 LINGUAGEM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 14 3.5.2 IMPLEMENTAÇÕES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 14 3.6 MÁQUINA VIRTUAL PYTHON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 15 4 PROJETO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 16 REFERÊNCIAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 17 6 1 INTRODUÇÃO Atualmente é crescente a produção e utilização dos chamados sistemas embutidos(SEs), que tratam-se de sistemas cuja finalidade principal não é a computação em si, embora ela seja essencial para o funcionamento do mesmo. Por exemplo não pesamos que estamos usando um computador quando assistimos um DVD, usamos um celular ou freamos um carro com ABS. Mas em todos estes casos existe computação envolvida e, portanto, existe necessidade tanto de hardware, quanto de software. Em termos de hardware, um SE geralmente possui os recursos estritamente necessários para sua implementação, o que significa, por exemplo, a utilização de um processador de custo menor e uma quantidade de memória reduzida. No que diz respeito ao software, um sistema embutido, assim como qualquer outro sistema computacional consiste em pelo menos uma aplicação que implementa a utilidade do sistema (por exemplo: reproduzir um vı́deo, fazer uma ligação, ou frear um carro) e de uma base sobre o qual a aplicação executará, chamada de Sistema Operacional (SO). Como muitos dos sistemas embutidos só possuem uma aplicação, a distinção entre esta e o SO muitas vezes não é clara, ou é até inexistente já que ambos podem ser implementados como um único programa. Neste caso uma das principais desvantagens é a não reutilização do código, que poderia pertencer ao SO, e ser usado em outros sistemas embutidos possivelmente diferentes do SE para o qual a aplicação original foi desenvolvida. Por outro lado fazer um SO separado da aplicação, mas extremamente genérico e cheio de recursos, pode tornar seu uso proibitivo em SEs, já que eles possuem limitações quanto a recursos de hardware. Uma solução seria fazer um SO distinto da aplicação, mas que fosse customizado em função da mesma. Por exemplo, não existe necessidade que a funcionalidade de gerenciamento de memória virtual esteja presente em uma aplicação que residirá em um hardware que não possuirá discos. Ou ainda, não existe necessidade de incluir em um SO funcionalidades de rede se a aplicação destinada a ele irá operar apenas localmente. O SO, customizado em função da aplicação da qual ele suportará é chamado de SO orientado à aplicação. O Sistema Operacional EPOS: Embedded Parallel Operating System, atualmente desenvolvido no Laboratório de Integração Software Hardware (LISHA) do Departamento de Informática e Estatı́stica (INE) desta universidade, é um exemplo de SO orientado à aplicação que vem sendo utilizado na construção de sistemas embutidos. 7 As linguagens de programação consistem em uma das principais ferramentas para se desenvolver aplicações e programas de computador de um modo geral, sejam eles para SEs ou não. Mas para que o computador possa executar os programas escritos em tais linguagens é necessário que exista uma ”conversão”do mesmo para o chamado código de máquina, que o processador é capaz de interpretar. Pode haver a tradução do programa como um todo para o código de máquina, o que é conhecido como compilação ou, para cada conjunto de construções de um programa, pode-se tomar uma ação, na medida em que o programa está sendo executado, o que é chamado de interpretação. Pode-se ainda usar-se destes dois processos, ou seja, é possı́vel traduzir todo um programa para uma linguagem intermediária e posteriormente executá-lo interpretando-o. Neste caso o interpretador é comumente chamado de Máquina Virtual e a linguagem intermediária de byte code. Assim sendo a Máquina Virtual é o interpretador que converterá as construções do byte code em ações a serem realizadas pela máquina real, o processador, na medida em que o programa é executado. O sistema operacional EPOS, por exemplo, foi desenvolvido em sua maior parte na linguagem de programação C++ e as aplicações para ele podem ser escritas atualmente em C e em C++. A linguagem de programação Python em sua implementação oficial, utiliza o mecanismo de compilação-interpretação sobre os programas escritos nela, apesar de não existirem dois programas distintos, um para compilar e outro para interpretar, como será detalhado no decorrer deste trabalho. A principal vantagem da abordagem compilação-interpretação é que o byte code gerado pode ser executado em diferentes máquinas virtuais, cada uma destinada, por exemplo, a uma máquina real diferente, sem a necessidade teórica de re-compilar o programa original. A proposta deste trabalho é de viabilizar a execução de programas em byte code Python no Sistema Operacional EPOS. Para atingir tal objetivo, será necessário fazer com que a Máquina Virtual Python interaja com componentes do EPOS. 8 2 OBJETIVOS 2.1 OBJETIVO GERAL Adaptar a Máquina Virtual Python de modo que ela trabalhe juntamente com o Sistema Operacional EPOS, porporcionando ao mesmo um suporte de aplicações em byte code Python. 2.2 OBJETIVOS ESPECÍFICOS • Conhecer as instruções da Máquina Virtual Python (PVM) , assim como a base de sua organização. • Conhecer os principais componentes do Sistema Operacional EPOS e compreender como eles se relacionam entre si. • Verificar quais funcionalidades da PVM poderão ser mapeadas em componentes do EPOS, assim como identificar quais de seus componentes existentes poderão realizar tais funcionalidades e quais, porventura, necessitarão ser criados. 9 3 REVISÃO TEÓRICA 3.1 SISTEMAS EMBUTIDOS Segundo (MARWEDEL, 2003) ”Sistemas Embutidos são sistemas de processamento de informações que se encontram embutidos em um produto maior e que normalmente não são diretamente visı́veis ao usuário.”Para que um sistema seja considerado embutido, ele deve apresentar várias das seguintes caracterı́sticas: • Estar conectado a ambientes fı́sicos por meio de sensores, para obter dados destes ambientes e por meio de atuadores para controlar o ambiente. • Deve ser confiável, em termos de disponibilidade, manutenibilidade, segurança e outros. • Deve ser eficiente em termos de baixos: consumo de energia, tamanho de código, peso, custo, etc. • Ser dedicado a uma certa aplicação. • Possuir interface dedicada com o usuário. • Pode possuir também restrições de tempo-real. • Ser hı́brido, no sentido de ser constituı́do tanto de partes digitais, como de partes analógicas Como consta em Fröhlich e Schröder-Preikschat (2000), no ano 2000, 98% do processadores produzidos no mundo foram destinados a produção de sistemas embutidos, e somente os 2% restantes destinados aos mercados de desktop e servidores. Isto evidencia a importância que tem tomado o mercado de sistemas embutidos e como conseqüência a necessidade do desenvolvimento de técnicas e metodologias para produzir tais sistemas. 10 3.2 SISTEMAS OPERACIONAIS 3.2.1 CONCEITOS Tanenbaum (2003) apresenta dois conceitos para sistemas operacionais. O primeiro deles diz que um sistema operacional pode ser visto como uma máquina estendida que fornece abstrações do hardware, tornando assim sua programação mais fácil. O segundo conceito vê o sistema operacional como um gerenciador de recursos que coordena a distribuição dos componentes de hardware, como processador, memória, dispositivos de entrada e saı́da, etc; entre vários programas que competem por eles. 3.2.2 EPOS O sistema operacional EPOS: Embedded Parallel Operating System foi desenvolvido durante a tese de doutorado de Antônio Augusto Medeiros Fröhich como meio de verificar os conceitos e técnicas do Projeto de Sistemas Orientado a Aplicações (Application-Oriented System Design), proposto por ele, Fröhlich (2001). Atualmente o EPOS continua a ser desenvolvido no Laboratório de Integração Software Hardware (LISHA) do Departamento de Informática e Estatı́stica (INE) desta universidade. Afirmar que o EPOS é um sistema operacional orientado à aplicação, significa dizer que, ele pode ser customizado em função da aplicação da qual ele suportará, oferecendo o suporte a hardware e funcionalidades apenas dos quais a aplicação necessita. Por exemplo, não existe necessidade que a funcionalidade de gerenciamento de memória virtual esteja presente em uma aplicação que residirá em um hardware que não possuirá discos. Ou ainda, não existe necessidade de incluir em um SO funcionalidades de rede se a aplicação destinada a ele irá operar apenas localmente. 3.3 LINGUAGENS DE PROGRAMAÇÃO As linguagens de programação, são um conjunto de regras léxicas, sintáticas e semânticas, através das quais podemos expressar nossas idéias e intenções e então implementar programas de computador. Existem vários aspectos sob os quais as linguagens de programação podem ser classificadas, um deles é a independência da máquina alvo. Em uma extremidade tem-se a linguagem do próprio processador, também conhecido como código de máquina. Como as linguagens de máquina possuem um alfabeto binário constituı́do somente de zeros e uns, é difı́cil a leitura e a escrita de programas nesta linguagem. Para facilitar esta tarefa, podem-se 11 usar de pequenas palavras chamadas de mnemônicos para designar as instruções de máquina. Basicamente disto consiste as linguagens Assembly. Entretanto as linguagens Assembly são igualmente dependentes de máquinas e por isso consideradas linguagens de baixo nı́vel. Em uma outra extremidade tem-se as linguagens de programação de alto nı́vel. Elas possuem esta denominação por serem, teoricamente, independentes de máquina. Uma das principais motivações para a criação das linguagens de alto nı́vel foi a necessidade do aumento da produtividade na construção de programas de computador. Em diversos textos e inclusive neste, na maioria das vezes em que o termo ”linguagem de programação”é usado, ele se refere a linguagens de alto nı́vel. Uma outra classificação de linguagens de programação que é relavante de ser mencionada neste trabalho é quanto a tipagem dos dados. De acordo com (PILGRIM, 2007) uma linguagem pode ser classificada em: • Linguagem Estaticamente Tipada Uma linguagem cujos tipos são determinados em tempo de compilação. A maioria das linguagens estaticamente tipadas implementam isto requerindo que o usuário declare todas as variáveis juntamente com os seus tipos, antes de usa-las. Java e C são linguagens estaticamente tipadas • Linguagem Dinamicamente Tipada Uma linguagem cujos tipos são descobertos em tempo de execução; o oposto de estaticamente tipada. VBScript (Visual Basic Script) e Python são dinâmicamente tipadas, porque elas determinam qual o tipo de uma variável no primeiro momento em que é atribuido um valor a ela. • Linguagem Fortemente Tipada Uma linguagem cujos tipos são sempre levados em consideração. Java e Python são fortemente tipadas. Se você tem um inteiro, você não pode trata-lo como uma string sem converte-lo de forma explı́cita. • Linguagem Fracamente Tipada Uma linguagem cujos tipos podem ser ignorados; o oposto de fortemente tipada. VBScript é fracamente tipada. Em VBScript, você pode concatenar a string ’12’ e o inteiro 3 para obter a string ’123’, e então trata-la como o inteiro 123, tudo sem nenhuma conversão explı́cita. 3.4 MÉTODOS DE IMPLEMENTAÇÃO DE LINGUAGENS DE PROGRAMAÇÃO De acordo com Sebesta (2000), existem três métodos gerais para se implementar linguagens de programação, são eles: compilação, interpretação pura e sistemas de implementação 12 hı́bridos. Compilação e interpretação pura podem ser considerados dois métodos que residem em extremidades opostas. Já sistemas de implementação hı́bridos reside no meio, entre estes dois extremos, por combinar compilação e interpretação. Diversas vezes, ao longo deste trabalho, será usado o termo compilação-interpretação, para se referir a este método. A seguir são explicados estes três métodos. 3.4.1 COMPILAÇÃO Como dito em Sebesta (2000) compilação trata-se de uma tradução, de um programa escrito em linguagem de alto nı́vel, para um programa escrito em linguagem de máquina equivalente. Uma das principais vantagens deste método é a alta velocidade de execução do programa compilado, já que este roda diretamente em um processador fı́sico. A compilação pode ser dividida em duas grandes fases: fase de análise, onde o programa fonte em linguagem de alto nı́vel é avaliado sob diversos aspectos e fase de sı́ntese, onde é gerado o programa objeto na linguagem da máquina alvo. A fase de análise se subdivide nas seguintes etapas: análise léxica, análise sintática e análise semântica. A fase de sı́ntese se subdivide em: geração de código intermediário e geração de código para a máquina alvo. Pode haver opcionalmente a etapa de otimização de código intermediário, antes da geração final de código. Cada uma destas etapas é discutida brevemente a seguir. 1. Análise léxica - Consiste na reunião dos caracteres do programa fonte em unidades léxicas, que como encontrado em (SEBESTA, 2000) são ”os identificadores, as palavras especiais, os operadores e os sı́mbolos de pontuação”. É nesta etapa em que o compilador pode encontrar sı́mbolos que não estão previstos no alfabeto da linguagem, o que caracteriza um erro léxico. 2. Análise sintática - Verifica se as unidades obtidas do analisador léxico, compõem construções sintáticas corretas, previstas na gramática da linguagem. 3. Análise semântica - Analisa se as construções sintáticas possuem sentido na linguagem em questão. É nesta análise em que é realizada a verificação de tipos de um programa. 4. Geração de código intermediário - A análise semântica está intimamente ligada a geração do chamado código intermediário, que consiste em uma linguagem geralmente independente de máquina e mais simples que a linguagem de alto nı́vel do programa fonte. 5. Otimização de código intermediário - Uma série de transformações conhecidas podem ser aplicadas ao código intermediário com o intuito de diminuir seu tamanho, ou de deixá-lo 13 mais rápido, ou ambos. É uma etapa opcional, que aumenta o tempo total do processo de compilação, mas que visa reduzir o tempo de execução do programa que será gerado. 6. Geração de código objeto - Trata-se de tradução do código intermediário para o código da arquitetura alvo. Eventualmente ainda nesta etapa podem ser feitas mais algumas otimizações dependentes de máquina. Como exemplos de linguagens cuja maioria das implementações se dá por meio de compiladores temos C, C++ e Ada. 3.4.2 INTERPRETAÇÃO PURA Em uma implementação que utilize interpretação pura, não existe tradução, o programa fonte é aos poucos convertido em resultados por um programa denominado interpretador. O interpretador atua como uma máquina virtual para a linguagem, buscando e executando as instruções do programa. Na execução de um programa compilado quem busca e executa as instruções é o processador ao invés do interpretador e quem é executado é um código em linguagem de máquina, ao invés de um código em alto nı́vel. Por lidar com código de alto nı́vel, torna-se fácil a implementação de operações de depuração, como aponta Sebesta (2000). O autor ainda coloca que uma séria desvantagem deste método é o tempo de execução de um programa, que vem a ser de 10 a 100 vezes mais lento que um equivalente compilado. Os scripts de shell Unix-like e os scripts .bat do MS-DOS, são exemplos de linguagens executadas em interpretadores. APL e LIST são exemplos de linguagens que possuem implementações como sistemas de interpretação pura. 3.4.3 SISTEMAS DE IMPLEMENTAÇÃO HÍBRIDOS Estes sistemas utilizam-se de compiladores para gerar um código intermediário que então é executado por interpretadores. Com o uso de compiladores, erros podem ser detectados antes do programa ser executado. Como o código intermediário gerado é mais simples que o código fonte original, a complexidade de implementação do interpretador é reduzida e o tempo de execução do programa é menor do que utilizando interpretadores puros. Como cita Sebesta (2000), a linguagem de programação Perl é implementada com um sistema hı́brido. As primeiras versões da linguagem Java também eram implementadas desta forma. Entretanto atualmente o código intermediário Java pode ser transformado em código nativo da máquina alvo, a medida que o programa executa. O código intermediário Java é 14 conhecido como byte code, e seu interpretador, aliado a um sistema de tempo de execução (run-time), consistem na chamada Máquina Virtual Java. Uma observação importante a se fazer é que embora as linguagens de programação geralmente são associadas a suas implementações mais comuns, em tese todas elas podem ser implementadas utilizando-se quaisquer uma dos três métodos gerais aqui mencionados. 3.5 PYTHON 3.5.1 LINGUAGEM Como pode ser visto na página oficial da linguagem Python. . . (2007b), Python é uma linguagem dinâmica, orientada a objetos e de propósito geral. De acordo com a classificação apresentada em 3.3 que também pode ser vista em Pilgrim (2007), Python é uma linguagem dinâmica, pois não são utilizados declarações explı́citas de tipo de dados, sendo o tipo determinado em tempo de execução. E ao mesmo tempo é uma linguagem fortemente tipada, pois uma vez que uma variável tem seu tipo determinado ele é levado em consideração, determinando quais as operações que a variável suporta e quais operações são proibidas. 3.5.2 IMPLEMENTAÇÕES De acordo com Python. . . (2007a) existem algumas implementações de Python distintas, além da implementação ”oficial”. Elas são brevemente descritas a seguir: • CPython É a implementação ”oficial”da linguagem, foi a primeira a ser feita e é a mais usada. Ela é escrita em C. É freqüentemente chamada simplesmente de ”Python”, mas para distinguir das outras implementações, ela é referida por CPython. • Stackess Python Trata-se de uma derivação (fork) do CPython, mas que não diverge muito da implementação principal. Desenvolvida por Christian Tismer, o objetivo desta implementação é o de minimizar o uso da pilha do C. Como conseqüência temos um Python significativamente mais rápido (cerca de 10que suporta um nı́vel de chamadas recursivas praticamente ilimitado, ao contrário de algums poucos milhares de nı́veis permitidos pelo CPython. • Jython Jython é uma reimplementação do Python, escrita em Java ao invés de C. Esta implementação compila um programa Python em byte codes Java e ao mesmo tempo permite que classes Java possam ser usadas a partir de um código Python. 15 • IronPython É uma implementação de Python que roda sobre a Common Language Runtime(CLR) da plataforma .NET da Microsoft. O lider de desenvolvimento deste projeto atualmente é Jim Hugunin. • PyPy Trata-se de um projeto financiado pela União Européia que tem por objetivo desenvolver uma implementação de Python, escrita em Python, utilizando para isto os aspectos reflexivos da linguagem. • Python for .NET É uma implementação experimental de Python que visa traduzir um programa escrito em Python em byte codes para a plataforma .NET da Microsoft. • Vyper É uma implementação experimental de Python escrita em Objective Caml (OCaml), uma linguagem funcional, orientada a objetos. 3.6 MÁQUINA VIRTUAL PYTHON A implementação do Python utilizada neste trabalho é a CPython. Ela utiliza o mecanismo de compilação-interpretação, ou seja, o Python converte um programa escrito em Python (linguagem) para uma linguagem intermediária (o byte code) que então é executado. Diferentemente de outras linguagens como por exemplo, Java, no Python o compilador e a máquina virtual estão em um mesmo executável, comumente chamado de interpretador. Na primeira vez em que o interpretador compila um programa, é criado um arquivo .pyc ou .pyo para armazenar o byte code gerado para que, numa segunda execução do mesmo programa, sejam evitadas compilações desnecessárias e para que se ganhe em desempenho. Como pode ser observado em Aycock (1998)A Máquina Virtual Python (PVM), ou seja, a parte do interpretador que realiza a interpretação de fato, é uma máquina de pilha. Isto significa que seus byte codes operam sobre elementos da pilha e colocam o resultado das operações também na pilha. O algoritmo básico realizado pela PVM é o de um interpretador classico: • Interpretar qual a operação do byte code a ser executado e buscar seus argumentos, se houver. • Executar o byte code Estes passos se repetem até que não existão mais instruções para executar. 16 4 PROJETO ”Esqueleto” Etapas/Estratégia Identificação dependencias libc e SO. ... 17 REFERÊNCIAS AYCOCK, J. Converting python virtual machine code to c. In: . [s.n.], 1998. ”Online”. Disponı́vel em: <http://www.python.org/workshops/1998-11/proceedings/papers/aycock211/aycock211.html>. Acesso em: 30 jun. 2007. FRöHLICH, A. A. Application-Oriented Operating Systems. Sankt Augustin: GMD Forschungszentrum Informationstechnik, 2001. (GMD Research Series, 17). FRöHLICH, A. A.; SCHRöDER-PREIKSCHAT, W. Operating Systems: are we finally ready to move forward after 30 years of stagnation? In: Proceedings of the Wild and Crazy Ideas Session at the 9th International Conference on Architectural Support for Programming Languages and Operating Systems. Cambridge, U.S.A.: [s.n.], 2000. p. 1. MARWEDEL, P. Embedded System Design. [S.l.]: Kluwer Academic Publishers, 2003. PILGRIM, M. How python’s datatypes compare to other programming lan. Dive Into Python. [s.n.], 2007. cap. 2.2.1. ”Online”. Disponı́vel em: guages. In: <http://www.diveintopython.org/getting to know python/declaring functions.html#d0e4188>. Acesso em: 30 jun. 2007. PYTHON Implementations. 2007. Disponı́vel em: <http://www.python.org/dev/implementations/>. Acesso em: 29 jun. 2007. PYTHON Programming Language – Official Website. 2007. Disponı́vel em: <http://www.python.org/>. Acesso em: 29 jun. 2007. SEBESTA, R. W. Conceitos de linguagens de programação. 4a . ed. Porto Alegrea: Bookman, 2000. TANENBAUM, A. S. Sistemas operacionais modernos. 2a . ed. São Paulo: Prentice Hall, 2003.