как да изградя компилатор за динамично въведен език?

Имам университетски проект, в който трябва да създам компилатор за език, избран от учителите, използвайки Bison и Flex в c++.

Езикът е обектно-ориентиран, събиран боклук, динамично типизиран език.

Работата е там, че аз и моят приятел просто сме объркани как да напишем mips кода за a.x, когато знаем само типа на a по време на изпълнение. нека да видим този псевдокод:

class A{private x;public A(){x=10}}
class B{public x;public B(){x=2}}
class C
{
   public static main(args)
   {
      n=input('integer');
      if(n>5)
         a=new A();
      else
         a=new B();
      write(a.x);
   }
}

Попитахме учителя, тя каза, че съхраняваме типовете на променливите в символната таблица, но ние даваме тези типове само по време на изпълнение, това означава, че трябва да изградим интерпретатор и това каза тя. но тя изглежда забрави, че имаме само стойността на n в кода на mips в някакъв регистър или в $sp(stack pointer), нямаме стойността на n в кода на c++, така че не можем да знаем тип a, освен ако няма mips код за tell the c++ program that the value of n is 1.

Можем да направим възможности за това какъв може да бъде типът на a, в горния код a е от тип A или B и mips кодът на a.x може да бъде нещо подобно:

beq type(a) A label1
li $a0,0(a)
li $v0 //code for print integer
syscall 
label1:raise exception

но нещата се усложняват в това твърдение a.b.c.d.etc, така че този подход е ужасен.

Моят приятел помоли учителя да принуди програмиста да напише типа, така че за a.b.c той трябва да напише A<a>.B<b>.C<c> например и резултатът е или изключение (грешно предаване или частен достъп), или a.b.c, но учителят отказа и така или иначе не ми харесва .

Методи, които познавам

1-запазете стойността в таблицата със символи: това ще направи генерирането на mips безполезно и програмата е чист C++ (вече не е нито компилатор, нито интерпретатор).

2-дефинирайте атрибут на стойност за символа в таблицата със символи, но нека кодът на mips промени тази стойност, добре, ако казахме в c++ int n и след това, докато генерираме код, кажем (в c++) printf("sw $v0,0(%d)",&x) тогава кодът на mips наистина ще промени x, защото съхранява стойността на v0 в адрес, който е същият като x адрес.

Но този подход изисква асемблерът и компилаторът да работят заедно паралелно и паралелът е просто сложен за нас.

И така, кой е най-добрият метод за справяне с това?


person niceman    schedule 09.05.2015    source източник


Отговори (1)


Ако превеждате вашия динамичен език на C++, бихте могли да поставите нашите обекти на вашия език като:

class DynamicLanguageObject
{
    int m_type;
    void* m_pValue; // stores int, double, char*, etc. depending on m_type
    map<string, DynamicLanguageObject*> m_fields;
};

и тогава изразът a.x във вашия динамичен език съответства на a.m_fields["x"] в C++. Този подход на речник-от полета показва колко динамични езици, включително JavaScript и Python, внедряват обекти.

Просто трябва да разберете как да внедрите хеш таблица в асемблерния език на MIPS.

person dan04    schedule 09.05.2015
comment
но какво да кажем за a.f()? Имам предвид какво ще кажете за методите? приемем, че f съществува както в A, така и в B, едно частно и едно публично - person niceman; 10.05.2015