🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.c
Article #309186

Re: jak skompilowac "a = 2*f+(d-g/3)*(9-i)"

#309186
From: (fir)
Date: Mon, 24 Apr 2017 15:53
146 lines
7338 bytes
W dniu poniedziałek, 13 lutego 2017 20:48:44 UTC+1 użytkownik (fir) napisał:
> a f d g i mozna zalozyc ze sa to rejestry asemblera (np 32 bitowe floaty) potrzebuje po prostu kodu ktory przerabialby to co powyzej na odpowiedni kod w wirtualnym asemblerze, cos w stylu
> 
> mov tmp1 2 
> mov tmp2 f 
> mul tmp1 tmp2 
> 
> mov tmp3 d 
> mov tmp4 g 
> mov tmp5 3 
> div tmp4 tmp3 
> sub tmp3 tmp4 
> 
> itd 
> (jako ze sam projektuje swoj asembler mozna tu sobie ulatwiac (np moge sobie dodac tyle rejestrow ile chce (i zalozyc ze wejsciowe 
> wyrazenia beda sie skladac tylko z 26 rejestrow od a do z i ze stalych)
> 
> jak to napisac/zrobic ?
> 
> sensowne hinty a jeszcze lepiej pseudokod bylby mile widziany, tnx

W dniu piątek, 21 kwietnia 2017 23:10:00 UTC+2 użytkownik (fir) napisał:
> W dniu piątek, 21 kwietnia 2017 22:51:12 UTC+2 użytkownik (fir) napisał:
> > W dniu piątek, 21 kwietnia 2017 20:00:46 UTC+2 użytkownik godek....@gmail.com napisał:
> > > W dniu piątek, 21 kwietnia 2017 18:01:23 UTC+2 użytkownik (fir) napisał:
> > > 
> > > > jak ja ostatnio pisalem prosty kompilator "wyrazen z jednym rowna sie i z czterema operatorami (+-*/) plus nawiasy" to to wcale nie do konca przypominalo 'petle z ifami lub ze switchem')
> > > 
> > > też ostatnio rozwijam kompilator na potrzeby pracy magisterskiej,
> > > ale kompilacja to jednak coś innego, niż parsowanie. w ogólnym
> > > przypadku celem parsowania jest zbudowanie drzewa rozbioru składni,
> > > choć oczywiście jeżeli format instrukcji jest prosty, często może
> > > wcale nie być nawet takiej potrzeby (co ma znaczenie, jak ktoś
> > > pracuje w językach takich jak C czy Pascal, gdzie obsługa drzew
> > > jest raczej uciążliwa). Jeżeli masz już drzewo rozbioru składni,
> > > to stworzenie interpretera dla języka jest raczej łatwym zadaniem.
> > > 
> > > Dla amatorów Lispa parsowanie jest zasadniczo umiarkowanie ciekawym
> > > zagadnieniem, natomiast kompilacja -- jak najbardziej. Najbardziej
> > > podstawowa technika kompilacji to konwersja do postaci, w której
> > > funkcje przekazują kontynutacje ("Continuation-Passing Style").
> > > 
> > > Na przykład, wyrażenie (+ (* x y) (/ z w))
> > > w postaci przekazującej kontynuacje miałoby postać
> > > 
> > > (pass* x y
> > >   (lambda (xy)
> > >     (pass/ z w
> > >        (lambda (zw)
> > >          (pass+ xy zw return)))))
> > > 
> > > gdzie pass+, pass/ i pass* to CPS-owe odpowiedniki działań arytmetycznych,
> > > a "return" to "nadrzędna kontynuacja" (np. koniec programu, albo
> > > powrót do wywołującej funkcji). Słowo kluczowe "lambda" ma takie samo
> > > znaczenie, jak w języku Scheme czy w lambda-rachunku, i podobne
> > > jak "function" w JavaScripcie.
> > > 
> > > Program w takiej postaci można już dość łatwo przekształcić
> > > do pseudo-asemblera:
> > > 
> > > xy := x * y
> > > zw := z / w
> > > result := xy + zw
> > > return
> > > 
> > > albo czegoś w tym rodzaju. Dalszy etap nosi w literaturze nazwę
> > > "register allocation" (i używa się do tego np. metod kolorowania
> > > grafów), a chodzi w nim o to, żeby tym zmiennym przechowującym
> > > wyniki pośrednie przypisać konkretne rejestry procesora (żeby zmniejszyć
> > > liczbę dostępów do pamięci)
> > > 
> > > lista źródeł, na których się opieram, jest dostępna tutaj:
> > > 
> > > https://www.quora.com/How-do-people-develop-lisps/answer/Panicz-Godek
> > 
> > 
> > jak wspomnielem nie chce mi sie zagladac do mojego kodu i przerywac cenny stan odpoczywania ale moge powiedziec z pamieci jak to dzialalo (chyba zreszta o tym tu pisalem)
> > 
> > jak mam np takie wyrazenie
> > 
> > x = (3*a+(c-2)/d+f)*g
> > 
> > to moj kod po prostu polegal na tym ze wykonywal powtarzalne przejscia i odkladal 'partykuly' na liste
> > upraszczajac wyrazenie
> > 
> > t1=3*a
> > x = (t1+(c-2)/d+f)*g
> > t2=(c-2)
> > x=(t1+t2/d+f)*g
> > t3=t2/d
> > x=(t1+t3+f)*g
> > t4=t1+t3
> > x=(t4+f)*g
> > t5=(t4+f)
> > x=t5*g
> > t6=t5*g
> > x=t6
> > 
> > sama liste 
> > t1=3*a
> > t2=(c-2)
> > t3=t2/d
> > t4=t1+t3
> > t5=(t4+f)
> > t6=t5*g
> > x=t6
> > 
> > na asm juz jest przerobic banalnie
> > 
> > mov t1,3
> > mul t1,a
> > mov t2,c
> > sub t2,2 ...itd
> > 
> > algorytm jest uwaam dobry i nie bardo prypomina switcha w petli (bo te operacje sa dosyc uniformiowane i dzialaja w 'multipasie' ) aczkolwiek zakodowalem dokladnie to ale mam wrazenie mniej elegancko niz by sie dalo... mozna by napisac pseudokod jak to zrobic ladniej i prosciej, (ew nieco bardziej ogolnie dla wiekszego seta operatorów), moze troche pozniej cos skrobne
> 
> mozliwe jest ze detale tego algorytmu wymagaja wlasnie malej 'konsyderacji'
> ogolnie jesli te operacje upraszczajace mialbym juz zakodowane i nazwalbym je
> - zdejmij_mnozenie
> - zdejmij_dzielenie
> - zdejmij_maly_nawias
> - zdejmij_dodawanie
> - zdejmij_odejmowanie
> 
> to jak puscis to w petli by to dzialalo jak najlepiej?
> (ciekawe pytanie, ktos ma chec odpowiedziec?)


ponawiam pytanie, bo w sumie jest ono ciekawe..
tak jak wspomnailem jak mam wyrazenie typu

z= x+y/(4*B/(7+c)-r)

to 'skompilowac' to moge przez sukcesywne przepisywanie tego wyrazenia przez 'zdejmowanie' par typu a+b a/b a*b a-b 

powiedzmy ze mam jus nawet napisane te funkcje ktore to robia "zdejmij('+')" zdejmij('-') gdzie tylko podaje oparator

pytanie jest takie 
1) jak w petli wywolywac te funkcje by to bylo w miare rozsądne (jedno zdjecie od razu generuje asma, jako ze zdejmuje oczywiscie te ktore mozna wykonac najpierw, tak ze po zdjeciu wszystkich mam po prostu wygenerowany kod)

2) czy da sie to rozszezrzyc na dowolne operatory (glownie te znane z c)? 

obcenie dla tych 4rech operatorow mam to napisane ale 
nadejdzie taki moment ze bede to chcial rozszerzyc na wszystkie

(pewnie sam sobie wtedy odpowiem na to pytanie ale wymaga ono wydaje sie odrobine pomyslunku)
Technical Details
Message-ID: <dfc4e09e-76ef-4521-8e76-a0630b9f7bff@googlegroups.com>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed2.atman.pl!newsfeed.atman.pl!goblin3!goblin.stu.neva.ru!news.misty.com!border2.nntp.dca1.giganews.com!nntp.giganews.com!c45no5228827qtb.1!news-out.google.com!v18ni3241ita.0!nntp.google.com!c26no1027019itd.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail
References: <6a6e4980-b3cc-41eb-8280-e080801f9db8@googlegroups.com>

Show Full Headers
Complete Article Headers
X-Received: by 10.200.45.49 with SMTP id n46mr12676348qta.64.1493049200510;        Mon, 24 Apr 2017 08:53:20 -0700 (PDT)
X-Received: by 10.157.13.170 with SMTP id 39mr158919ots.18.1493049200458; Mon, 24 Apr 2017 08:53:20 -0700 (PDT)
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed2.atman.pl!newsfeed.atman.pl!goblin3!goblin.stu.neva.ru!news.misty.com!border2.nntp.dca1.giganews.com!nntp.giganews.com!c45no5228827qtb.1!news-out.google.com!v18ni3241ita.0!nntp.google.com!c26no1027019itd.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail
Newsgroups: pl.comp.lang.c
Date: Mon, 24 Apr 2017 08:53:20 -0700 (PDT)
In-Reply-To: <6a6e4980-b3cc-41eb-8280-e080801f9db8@googlegroups.com>
Complaints-To: groups-abuse@google.com
Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=5.172.255.201; posting-account=Sb6m8goAAABbWsBL7gouk3bfLsuxwMgN
NNTP-Posting-Host: 5.172.255.201
References: <6a6e4980-b3cc-41eb-8280-e080801f9db8@googlegroups.com>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <dfc4e09e-76ef-4521-8e76-a0630b9f7bff@googlegroups.com>
Subject: Re: jak skompilowac "a = 2*f+(d-g/3)*(9-i)"
From: "(fir)" <profesor.fir@gmail.com>
Injection-Date: Mon, 24 Apr 2017 15:53:20 +0000
Lines: 189
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit