專利名稱:增量連接系統(tǒng)的制作方法
技術(shù)領(lǐng)域:
本發(fā)明涉及計(jì)算機(jī)輔助軟件工程(CASE),尤其涉及面向人的目標(biāo)編程系統(tǒng)(HOOPS),該系統(tǒng)為計(jì)算機(jī)程序建立提供了交互和動(dòng)態(tài)環(huán)境。面向人的目標(biāo)編程系統(tǒng)(HOOPS)使程序員得以由優(yōu)化增量編譯程序而對(duì)計(jì)算機(jī)程序中的微小的顆粒源碼進(jìn)行編輯。本發(fā)明的主題是一增量連接程序,它在HOOPS中操作以生成由一個(gè)輸入程序所用的文件。本發(fā)明是以使用通用的面向目標(biāo)編程的(OOP)語言、C++作為最佳實(shí)施例的,但其原理也適用于面向目標(biāo)的以及過程計(jì)算機(jī)編程語言,本發(fā)明亦可用于建立使用常規(guī)的和OOP語言的程序。
OOP是建立用戶使用方便的以及智能計(jì)算機(jī)軟件的最佳環(huán)境。OOP的要素是數(shù)據(jù)密封性(data encapsulation),繼承性(inheritance)以及多形性(Polymorphism)。這些元素可以用于產(chǎn)生圖形用戶接口(GUI),尤其是產(chǎn)生具有圖符、鼠標(biāo)光標(biāo)以及選項(xiàng)單視窗環(huán)境的為特征的。所構(gòu)成的GUI。雖然這三種要素屬OOP語言所共有,但在實(shí)施方式上大部分OOP語言彼此間有很大的區(qū)別。
OOP語言的例子包括Smalltalk、目標(biāo)Pascal和C++。Smalltalk實(shí)際上不止是一種語言,更準(zhǔn)確地講,它應(yīng)該被認(rèn)為一種編程環(huán)境。該語言是在70年代早期施樂普拉阿圖研究中心(PARC)的研究部開發(fā)的。在該語言中,一個(gè)信息被送到一個(gè)目標(biāo)以對(duì)其進(jìn)本身行評(píng)價(jià)。信息完成的任務(wù)類似于在常規(guī)編程語言中的功能調(diào)用。程序員無需關(guān)心數(shù)據(jù)類型而只須關(guān)心生成正確順序的信息及使用正確的信息。Object Pas-cal是用于蘋果公司的Machintesh 計(jì)算機(jī)上的語言,蘋果公司在Pascal語言的設(shè)計(jì)者一尼古拉斯·沃斯(Niklaus.With)—的合作下開發(fā)出了Object Paseal語言。C++語言則是由斯托斯特拉普(Bjarne Stroustrup)在1983年在AT&T貝爾實(shí)驗(yàn)室開發(fā)而成的,它出C語言的擴(kuò)展。C++的主要概念是分類,它是用戶定義型的。分類提供了面向目標(biāo)的編程特性。C++模型與C模型相兼容而且可隨意聯(lián)接,從而現(xiàn)有的C程序庫(kù)可由C++程序所用。最廣泛使用的基于目標(biāo)和面向目標(biāo)的編程語言源于60年代由挪威的戴沃(O-J.Dah1)梅·阿漢(B.Myhrhaug)以及耐·培得(K.Nygard)所開發(fā)的Simula語言。有關(guān)OOP的信息可參見布克(Grady Booch)所著的“Object Oriented Design with Applications”(Benjimin/Cum-mings Publishing Co.,Inc.,Readwood city,California,1991)。
運(yùn)行一個(gè)計(jì)算機(jī)程序的完整過程涉及把程序員寫出的源碼譯為機(jī)器可執(zhí)行的格式,通常稱為目標(biāo)碼,然后再執(zhí)行該目標(biāo)碼。翻譯的過程是由編譯程序或解釋程序完成。在解釋程序中,翻譯是隨程序的運(yùn)行而進(jìn)行的;而在編譯程序中,則是在運(yùn)行該程序之前就進(jìn)行翻譯并將結(jié)果作為目標(biāo)碼存貯起來。也就是說,在一般的編譯和執(zhí)行系統(tǒng)中,翻譯和執(zhí)行是分開進(jìn)行的,即編譯只進(jìn)行一次。而在解釋系統(tǒng)中,例如Smalltalk解釋程序,兩者是順序進(jìn)行。因?yàn)橹钡揭粋€(gè)目標(biāo)被實(shí)現(xiàn)之前,編程環(huán)境的性質(zhì)不允許指定專用寄存器或地址空間,所以,Smalltalk需要解釋程序。
一個(gè)編譯程序包括三部分;詞法分析程序,語法分析程序,以及代碼生成程序。詞法分析程序的輸入是代表高級(jí)語言程序的一序列字符。詞法分析程序?qū)⒃撔蛄蟹譃橐粋€(gè)標(biāo)記序列以輸入到語法分析程序。語法分析程序進(jìn)而將該序列標(biāo)記分為指令并利用語法規(guī)則的數(shù)據(jù)庫(kù)來確定是否每條指令的語法正確與否。若不正確,則產(chǎn)生錯(cuò)誤信息。若正確,則指令被分解為一基本指令系列。這些基本指令被送至代碼生成程序以產(chǎn)生低級(jí)語言。代碼生成程序本身通常又分為三部分;中間代碼生成,代碼優(yōu)化,以及代碼生成?;径?,代碼生成程序接收來自語法分析程序的輸出并生成機(jī)器語言碼。
為有助于軟件開發(fā)而開發(fā)出了增量編譯程序,其中,編譯程序在批處理操作中生成用于接收的一條語句或一組語句的代碼,而與稍后生成的用于其他語句的代碼無關(guān)。增量編譯的優(yōu)點(diǎn)在于只有被一轉(zhuǎn)變所影響的代碼才被編譯。這一行為導(dǎo)致了極快的編譯和調(diào)試代碼的周期。
優(yōu)化編譯程序產(chǎn)生高度優(yōu)化的目標(biāo)碼。從而在許多情況下使得在源級(jí)進(jìn)行調(diào)試比一個(gè)非優(yōu)化編譯程序更困難。這一問題源于這一事實(shí),即雖然一個(gè)例行程序?qū)⒈痪幾g以給出適當(dāng)?shù)拇鸢福?jì)算該答案的確切方式可能與源碼中描述的大相徑庭。優(yōu)化編譯程序可以實(shí)現(xiàn)的一些事情,包括刪除被確認(rèn)屬不會(huì)影響最終結(jié)果的代碼或變量,將非變量代碼移出循環(huán),合成公用碼,在變量不再需要時(shí)重新使用分配給這些變量的寄存器等等。如此,源碼到目標(biāo)碼或目標(biāo)碼到源碼的映射在給定某些優(yōu)化時(shí)可能會(huì)有困難。由于變量的值可能并非在例行程序中任意位置處總是可用的,所以可能難于校驗(yàn)變量的值。在優(yōu)化代碼中修改變量值既使不是完全不可能,也是尤為困難。除非專門說明為易失的,否則編譯程序會(huì)“記住”分配給變量的值并可能在以后的代碼中不再讀該變量而使用“已知”的值。因此,在該值中的改變產(chǎn)生了錯(cuò)誤的程序結(jié)果。
雖然在先有技術(shù)的計(jì)算機(jī)程序設(shè)置、測(cè)試以及開發(fā)中有許多優(yōu)點(diǎn),但已知的軟件開發(fā)工具仍給程序員帶來極大負(fù)擔(dān),從而通常要求有直覺的洞悉力。其次,常規(guī)的面向批處理的編程系統(tǒng)需要很長(zhǎng)的編輯——編譯——測(cè)試周期,這對(duì)編程的創(chuàng)造性行為帶來的極大的不利影響。
一旦在常規(guī)編程系統(tǒng)中完成了編譯,稱為裝入程序的程序?qū)?zhí)行裝入和連接編輯這樣兩個(gè)功能。該裝入處理包括獲取可重新定位的機(jī)器碼,修改可重新定位的地址,并把存儲(chǔ)器中修改后的數(shù)據(jù)和指令放入適當(dāng)?shù)奈恢谩6B接編輯程序則從幾個(gè)有可能重新定位的機(jī)器碼的文件中生成一個(gè)程序。這些文件可以是幾個(gè)不同編譯的結(jié)果。
因此,本發(fā)明的一個(gè)目的是提供一種增量連接程序,該增量連接程序在用于建立計(jì)算機(jī)程序的面向人的交互動(dòng)態(tài)處理中操作。
在交互動(dòng)態(tài)的建立過程中,程序建立可由增量程序模式(稱為項(xiàng)目Project)和三個(gè)主要功能性交互而成。一個(gè)程序被成型為語義單元,該語義單元被稱之為成分并由稱為特性的命名數(shù)據(jù)項(xiàng)目表構(gòu)成。不是象常規(guī)系統(tǒng)那樣把程序作為一個(gè)松散的文件集合存儲(chǔ)起來。本發(fā)明的面向人的目標(biāo)編程系統(tǒng)把項(xiàng)目中有關(guān)程序的所有信息存起來。本發(fā)明的計(jì)算機(jī)程序的建立有助于使程序員的生產(chǎn)力大為提高。
根據(jù)本發(fā)明,提供了一種增量連接程序,它在HOOPS運(yùn)行并且其功能連到現(xiàn)有的執(zhí)行程序,從而避免對(duì)一組完整的目標(biāo)文件進(jìn)行再處理。在本發(fā)明的實(shí)施中,計(jì)算機(jī)程序被成型為一個(gè)部件集,為計(jì)算機(jī)程序提供模型的部件被存儲(chǔ)以便在建立處理中被存取。存儲(chǔ)的部件被依序存取,而且用一個(gè)編譯程序計(jì)算與每個(gè)部件關(guān)聯(lián)的相關(guān)性以開發(fā)一個(gè)相關(guān)性表。然后,根據(jù)相關(guān)性表編譯部件以產(chǎn)生一個(gè)更新過的目標(biāo)模型。最后,更新的目標(biāo)模型通過對(duì)現(xiàn)有可執(zhí)行文件的更新而被連接。
本發(fā)明的最佳實(shí)施例以C++完成的并用C++C以及匯編語言進(jìn)行的程序建立,這些語言是當(dāng)前最流行使用的。本發(fā)明的程序的建立一般可用這三種語言完成。雖然本發(fā)明本身是以面向目標(biāo)的編程語言寫成的面向目標(biāo)的程序,但其并不僅限于以面向目標(biāo)的程序語言建立程序。本發(fā)明可同樣用于以過程語言建立程序。進(jìn)而,本發(fā)明不限于C++語言,它也可由其他編程語言實(shí)現(xiàn)。而且本發(fā)明不限于只用于這三種語言;也就是說,本發(fā)明的原理可用于更為一般應(yīng)用的面向人的目標(biāo)編程系統(tǒng)。
上述的以及其它目的,所涉及的方面及其優(yōu)點(diǎn)可從下面參考附圖對(duì)本發(fā)明的最佳實(shí)施例的詳細(xì)敘述有更好的理解。其中,
圖1展示了一種可以支持高分辨率圖形顯示設(shè)備和光標(biāo)指示設(shè)備(例如鼠標(biāo)器)的常規(guī)計(jì)算機(jī)系統(tǒng),本發(fā)明即可在該系統(tǒng)上實(shí)施;圖2是圖1所示計(jì)算機(jī)系統(tǒng)的主要部件框圖;圖3是構(gòu)成一個(gè)程序的部件集的概念形式框圖;圖4是本發(fā)明的原理功能框圖;圖5A到圖5D為通過建立狀態(tài)(BuildState)寄存編輯變化的邏輯流程圖;圖6是根據(jù)本發(fā)明在建立處理操作的第一階段確定可能的部件的邏輯流程圖;圖7是根據(jù)本發(fā)明在建立處理操作的第二階段對(duì)界面進(jìn)行處理的邏輯流程圖;圖8是根據(jù)本發(fā)明在建立處理操作的第三階段對(duì)實(shí)施進(jìn)行處理的邏輯流程圖;圖9是根據(jù)本發(fā)明由編譯程序調(diào)用的獲取說明(GetDedaration)功能的邏輯流程圖;圖10A和10B展示了有條件地編譯功能(CorditionallyCompile function)的邏輯流程圖;圖11是使用本發(fā)明時(shí)表示一個(gè)通常數(shù)目的窺視窗口的計(jì)算機(jī)屏幕的圖示表示;圖12展示了根據(jù)本發(fā)明的計(jì)算機(jī)屏幕的圖示表示,該表示展示了一個(gè)瀏覽窗(Browser)接通時(shí)的情況;圖13展示了圖12中瀏覽窗線路接通時(shí)計(jì)算機(jī)屏幕的圖示表示;圖14展示了樹狀窺視窗中部分?jǐn)U展的項(xiàng)目的計(jì)算機(jī)屏幕圖示表示;圖15至圖18展示了在編譯一個(gè)部件的處理過程中顯示的一些屏幕;圖19展示了根據(jù)一個(gè)最佳實(shí)施例的內(nèi)部和交叉庫(kù)調(diào)用;圖20展示了根據(jù)一個(gè)最佳實(shí)施例的一組安排分類(fix-up dasses);圖21展示根據(jù)一個(gè)最佳實(shí)施例的一個(gè)連接區(qū);圖22展示根據(jù)一個(gè)最佳實(shí)施例的目標(biāo)碼存儲(chǔ);圖23展示根據(jù)一個(gè)最佳實(shí)施例的裝入庫(kù);圖24展示根據(jù)一個(gè)最佳實(shí)施的裝入模塊的存儲(chǔ)器映射;圖25展示根據(jù)一個(gè)最佳實(shí)施例的不同類型的基準(zhǔn)以及這些基準(zhǔn)的連接程序的修改;以及圖26,27,28和29是流程圖,示明了根據(jù)一個(gè)最佳實(shí)施例的與連接關(guān)聯(lián)的邏輯。
參照?qǐng)D1,示出了一個(gè)常規(guī)計(jì)算機(jī)10。該計(jì)算機(jī)10包括一系統(tǒng)單元12,一個(gè)高分辨率顯示設(shè)備14,例如一個(gè)陰極射線管(CRT)或者一個(gè)液晶顯示器(LCD)。除去要求用于顯示視窗系統(tǒng)通常是圖形用戶界面需要高分辨率這一點(diǎn)十分重要以外,這種顯示類型并不重要。用戶對(duì)計(jì)算機(jī)的輸入由鍵盤16以及光標(biāo)指示設(shè)備,例如鼠標(biāo)器18完成。鼠標(biāo)器18與鍵盤16相連并進(jìn)而與系統(tǒng)依次相連。而且鼠標(biāo)器18可連到系統(tǒng)單元12的一個(gè)專用或串行口。圖1所示的計(jì)算機(jī)是Ap-ple Machintosh(蘋果計(jì)算機(jī)的注冊(cè)商標(biāo))以IBM PS/2。其他機(jī)型可包括各種工作站,例如IBM RISC System/6000以及Sun Microsystems計(jì)算機(jī)。
圖2更為詳細(xì)地展示了圖1所示計(jì)算機(jī)的基本部件。系統(tǒng)單元12包括一個(gè)連到總線24上的中央處理單元(CPU)21,隨機(jī)存取存儲(chǔ)器(RAM)22,以及只讀存儲(chǔ)器(ROM)23。CPU21可以是任何商業(yè)化的微處理器,例如Motorpla 68030和68040(它們通常用于Apple Maethintosh 計(jì)算機(jī)中)或In-tel 80386及80486(它們通常用在IBM PS/2計(jì)算機(jī)中)。其他微處理器,例如RISC(用于減少指令集計(jì)算機(jī))微處理器(通常用于工作站)也可使用。ROM24存儲(chǔ)用于CPU的基本微碼,包括基本輸入/輸出系統(tǒng)(BIOS)。計(jì)算機(jī)系統(tǒng)10的操作系統(tǒng)(OS)也可存在ROM24中,或者把OS作為初始程序裝入(IPL)的一部分存入RAM22中。RAM22也用于存儲(chǔ)部分應(yīng)用程序以及執(zhí)行該程序過程中生成的臨時(shí)數(shù)據(jù)總線24可以是Apple NuBus,IBM MicroChannel或工業(yè)標(biāo)準(zhǔn)之一的總線。例如ISA(工業(yè)標(biāo)準(zhǔn)適配器)或EISA(擴(kuò)展的工業(yè)標(biāo)準(zhǔn)適配器)。
與總線24相連的還有多個(gè)輸入/輸出(I/O)適配器,包括一個(gè)用戶接口適配器25以及一個(gè)I/O適配器26。鍵盤16與用戶接口適配器25相連,而I/O適配器26與軟盤驅(qū)動(dòng)器27和硬盤驅(qū)動(dòng)器28相連。軟盤驅(qū)動(dòng)器27允許把數(shù)據(jù)和程序讀寫到可擦除介質(zhì),而硬盤驅(qū)動(dòng)器28通常存儲(chǔ)頁入頁出RAM22的數(shù)據(jù)和程序。顯示設(shè)備14通過顯示適配器29而與總線24相連。通訊適配器30為網(wǎng)絡(luò)提供接口。其他支持電路(未示出)為集成電路芯片,它們被連到總線24和/或CPU21。這些芯片包括例如控制總線24上的信息量的總線主控芯片??偩€24在某些計(jì)算機(jī)中可以是雙總線;一個(gè)數(shù)據(jù)總線和一個(gè)允許在圖形用戶界面中需要的高速顯示操作的顯示總線。
定義程序如在本發(fā)明中所敘述的,一個(gè)HOOPS程序包括一個(gè)叫做“項(xiàng)目”的不可建立的部件以及一個(gè)“可建立的部件”的集合。不可建立的組成,部分亦可被存儲(chǔ),但在本敘述中,只要到不合格的部件,就是指一個(gè)“可建立的部件”,不可建立的部件在建立操作中將不被編譯。
部件一個(gè)部件有一個(gè)唯一的標(biāo)識(shí)并被命名。不同的部件由稱為ID的不同形式的唯一標(biāo)識(shí)符加以區(qū)分。有一個(gè)稱為空ID(NullID),它不屬于任何部件。該ID在一個(gè)部件生成時(shí)被賦予而且在該部件存在期間不會(huì)改變。若一個(gè)部件被刪除了,它的ID不會(huì)再被使用。實(shí)際中,ID通常是數(shù)字的。
一個(gè)部件也有一個(gè)“名字”,它包括一串沒有白空格的文本。不同部件不必須要求有不同名字??梢垣@得包括所有部件的表(可能是空的),其中所有部件的名字與某些給定文本串相吻合。一個(gè)部件的名字可以在該部件存在期間被改變?nèi)我獯巍?br>
每個(gè)可建立的部件件都與特定的計(jì)算機(jī)語言相關(guān)。實(shí)踐中,計(jì)算機(jī)語言通常由一串文本標(biāo)識(shí)。每一計(jì)算機(jī)語言有一個(gè)與其相關(guān)的編譯程序以供當(dāng)以該語言編譯任何部件所用,實(shí)際上,可能使一種給定的計(jì)算機(jī)語言與不止一個(gè)編譯程序相關(guān)聯(lián)。在本例中,部件必須記錄語言以及標(biāo)識(shí)該特定編譯程序的某些方式。
一種特定的語言有一與之相關(guān)的特定的部件種類集合以及一特定的特性實(shí)施集,通??赡苊恳环N類都不同。如此,在一特定語言中的區(qū)別語義元素可以根據(jù)需要以不同方式進(jìn)行組合。
部件有“建立狀態(tài)(Build States)”?!敖顟B(tài)”是來自“不要編譯”(Never Compile)、“已編譯的”(Compiled)、“需要編譯”(NeedTo Compile),“不確定”(Uncertain),“被編譯”(Be-ing Compiled),“編譯錯(cuò)誤”(CompileError),以及“不確定錯(cuò)誤”(UncertainError)的表中的一個(gè)取值。實(shí)際中,這些值通常是數(shù)碼,每個(gè)部件有稱為“界面建立狀態(tài)(Interface BuildState)”和“實(shí)施建立狀態(tài)(Implementation Build State)”的一對(duì)?!敖顟B(tài)”無論是可建立的或不可建立的,每個(gè)部件都有這兩個(gè)建立狀態(tài)。對(duì)不可建立的部件而言,這些建立狀態(tài)都是“不可編譯”的。
“建立狀態(tài)”可被存取和改變。可以把一個(gè)部件的”建立狀態(tài)”再次設(shè)置到同一值并且不會(huì)導(dǎo)致任何影響。改變一個(gè)“建立狀態(tài)”可能完好地定義邊界效應(yīng),便如改變有同樣或不同部件的一特性的“建立狀態(tài)”,或者例如從一個(gè)有改變的表或一個(gè)有錯(cuò)誤的表中加入或刪除等此參考項(xiàng)。
部件用于表達(dá)語義語言元素。表達(dá)的方式取決于將被模塊化的特定計(jì)算機(jī)語言。例如在C++中,由部件表達(dá)的語言元素表格包括全局?jǐn)?shù)據(jù),全局功能,分類,數(shù)據(jù)成員,成員功能,typedef,Rnums,仿真程序,宏指令,“或”運(yùn)算以及結(jié)構(gòu)。通常,每個(gè)語義元素將有一相關(guān)聯(lián)的區(qū)別種類。
特性一個(gè)部件包括一個(gè)命名的“特性”(Property)集合。一個(gè)特性表示與該部件有關(guān)的一些數(shù)據(jù)。在給定部件的ID和特性名之后,可以存取和檢索這些數(shù)據(jù)。特性名字通常由標(biāo)識(shí)名字的數(shù)字(有時(shí)稱為記號(hào))在內(nèi)部表示。也有不屬于特性的區(qū)別特性名,叫做“空特性”(NullProperty)。
與一給定特性相關(guān)的數(shù)據(jù)對(duì)不同的的部件而言是不是的。改變一個(gè)部件給定特性的數(shù)據(jù)并不意味著改變用于任何其他部件的同一特性的數(shù)據(jù)。但是,有可能在一個(gè)部件的一個(gè)特性中的改變會(huì)導(dǎo)致同一或另一部件的另一特性的改變。
“引用(reference)”包括一個(gè)ID和一個(gè)特性名。一個(gè)引用唯一地標(biāo)識(shí)特定的部分的特性數(shù)據(jù)。一個(gè)引用通常被松散地使用,就象它是部件和/或與之相關(guān)的特性。實(shí)際上,一個(gè)引用通常包含不在程序建立過程中直接使用的其他信息,從而標(biāo)識(shí)該特性中的哪種數(shù)據(jù)版本及哪種數(shù)據(jù)子節(jié)將被引用。
所有部件必須有特性“名(Name)”和“貯存器(Container)”,該特性“名”存有部件的名字?!百A存器”特性則包含了其中的特性名為“空特性”的一個(gè)單一引用。從任一部件開始并相繼由貯存器ID引用的部件取代前一部件將總是最終導(dǎo)致“項(xiàng)目部件”(Projeet Component)。該項(xiàng)目的“貯存器ID”是“空ID(NullID)”。如此,所有部件在項(xiàng)目中被描述。
建立特性(亦稱為部件建立表)以建立順序記錄最后建立中被正確編譯的特性表。相同的特性應(yīng)該在該表中最多出現(xiàn)一次。建立特性用于測(cè)試和調(diào)試。
項(xiàng)目部件一個(gè)項(xiàng)目是一個(gè)附帶有特性“變化表(Changalist)”和“錯(cuò)誤表(ErrorList)”的部件。特性變化表是一個(gè)引用用。這些引用描述部件以及最后一次建立以來發(fā)生了改變的特性。實(shí)際上,“變化表”可以由某種可以有效建立一個(gè)程序的過程中有效地存儲(chǔ)的多個(gè)表來表示。特性“錯(cuò)誤表”也是一個(gè)引用表。這些引用描述在最后程序建立過程中列為有錯(cuò)誤的部件。這些引用都有“錯(cuò)誤”特性。與每個(gè)引用相關(guān)的是一個(gè)數(shù)碼鍵,它用于關(guān)聯(lián)特定的“錯(cuò)誤”特性以確定一個(gè)專用消息的位置以及部件特定特性的一個(gè)特定子范圍。
可建立部件一個(gè)可建立部件必須有這些特性?!罢f明(Declaration)“目標(biāo)碼(ObjectCode)”、“客戶(Clients)”、“源引用(Source Ref-erence)”、“錯(cuò)誤”,并可有這些特性“界面(Interface)”、“實(shí)施(Implementation)”以及“成員(members)”。
“說明”特性表示用于編譯程序的一個(gè)數(shù)據(jù)高速緩沖存儲(chǔ)器。它可能在部件已被編譯之前是空的。實(shí)際上,它可被認(rèn)為是編譯程序符號(hào)表的入口,盡管存儲(chǔ)的狀況可能與編譯程序的內(nèi)部情況不同。
“目標(biāo)碼”特性表示了用于該部件的可執(zhí)行碼,它可能在部件被編譯前是空的,或者由于沒有目標(biāo)碼與該部件相關(guān)而是空的。實(shí)際上,它通常提供一個(gè)手段指向?qū)嶋H碼所存之處。
“客戶”和“源引用”特性是一對(duì)集合。它們包括一個(gè)引用和一個(gè)“相關(guān)性(dependency)”。一個(gè)相關(guān)性是一個(gè)變化表。變化可以表示為從一個(gè)區(qū)別的有限表串中選取的一個(gè)文本串。一個(gè)稱為“公開(Pubpic)”的區(qū)別的變化用來區(qū)分只在實(shí)施特性性中對(duì)部件的引用,這與界面特性中的應(yīng)用相反。一個(gè)相關(guān)性可表示為一個(gè)位向量,其中若第n位的變化在表中表示,則該位向量的第n位為“1”,否則為“0”。
錯(cuò)誤特性包括一個(gè)三個(gè)一組的表。每一組包括一個(gè)“鍵”,一個(gè)特性名,以及一個(gè)信息,一個(gè)鍵即為一個(gè)數(shù)碼標(biāo)識(shí)。一個(gè)給定鍵在特定的“錯(cuò)誤”特性中在一個(gè)時(shí)刻只出現(xiàn)一次,該特性名通常是“界面”或“實(shí)施”。該信息則是文本或/和圖形的某些部分。
“界面”和“實(shí)施”特性表示部件的源文本。該源文本可作為記號(hào)而不是作為文本存起來并在需要時(shí)以不同形式訪問。由這些特性表示的文本可通過編程環(huán)境中的人工編輯而予改變。一種可能性是把界面數(shù)據(jù)作為結(jié)構(gòu)區(qū)存起來,而從結(jié)構(gòu)區(qū)中,源文本可按需要重新構(gòu)造。
“成員”特性是引用集合(可能空的),每一引用用于“項(xiàng)目”中的每個(gè)部件,而“項(xiàng)目”將該部件作為其貯存器。
屬性一個(gè)部件有多個(gè)“屬性”。一個(gè)屬性為“真”或“假”。實(shí)際上,一個(gè)屬性通常是由存儲(chǔ)器的單比特值所表示的,由數(shù)字“1”和“0”表示的一個(gè)該屬性的真或假。所有部件都有“是可建立的(IsBuildable)”屬性。若該屬性為“真”,則該部件是可建立的;否則便為不可建立的。一個(gè)部件可能總是不可建立的或暫時(shí)不可建立的(因?yàn)槟承簳r(shí)條件的作用)。
可建立的部件也有“在內(nèi)部(Isinline)”屬性。當(dāng)該屬性為“真”時(shí),該部件的“實(shí)施”是公開的,這意味著另外的部件可以依賴于實(shí)施的改變。若其為“假”,則實(shí)施改變將不會(huì)導(dǎo)致其他部件改變。
可建立的部件還有“合成(IsSynthetic)”屬性。這一屬性對(duì)于在編譯程序在建立處理過程中生成的部件來說為“真”。而對(duì)程序員人工生成的部件為“假”。提供合成部件是使編譯程序生成與系統(tǒng)設(shè)定語言元素對(duì)應(yīng)的部件,系統(tǒng)需要設(shè)置語言元素,但其不必由程序員直接生成,實(shí)際上有可能將“合成”屬性從“真”改為“假”,例如當(dāng)一個(gè)合成的部件被人工編輯時(shí),但從“假”到“真”的反向改變是絕不允許的。合成部件通常沒有“界面”或“實(shí)施”特性,但無論在何種情況下,合成部件都使“界面”和“實(shí)施建立狀態(tài)”被編譯。
類別每一部件都有一“類別”(Kind)”。一個(gè)類別是指把部件劃分為例如共有同樣特性或同樣語言特定行為的各個(gè)組的一個(gè)文本串。大部分類別是專用于一種特定的計(jì)算機(jī)語言并用于指定語義區(qū)別語言元素。
然而,有一些是由系統(tǒng)定義的類別,它們分別為“項(xiàng)目”,“庫(kù)”,以及“貯存器”。這些類別只用于不可建立的部件。“項(xiàng)目”類別是“項(xiàng)目”部件的類別?!皫?kù)”類別則是用于連接到目標(biāo)碼的一個(gè)外部塊(例如一個(gè)共同庫(kù)或應(yīng)用程序)的部件的集合。類別“貯存器”則應(yīng)用于把其他部件分組歸類以便組織的部件。實(shí)際上,類別通常在內(nèi)部由數(shù)碼表示。
圖3提供了包括一個(gè)系列的部件31的程序的概念性的圖示。每個(gè)部件由一組特性組成,這組特性分為兩部分,即稱為界面的外部可見(公開)部分311以及實(shí)施(專用)部分312。如圖3所示,部件只依賴于另一個(gè)部件的界面。在一個(gè)項(xiàng)目中的所有部件被組織成樹狀結(jié)構(gòu),其底部為根的部件32(稱為項(xiàng)目部件)。如同本技術(shù)領(lǐng)域的一般技術(shù)人員可知的那樣,部件本身不必包含實(shí)體,但可以包括指向?qū)嶋H碼的存儲(chǔ)位置的指針。然而,這一樹結(jié)構(gòu)表達(dá)方式在展示一個(gè)程序的構(gòu)成上是有用的,因此,類似的樹結(jié)構(gòu)表示被用于其后所述的用戶屏幕之一。
圖4是一框圖,示出了本發(fā)明的三個(gè)主要功能性。它們是數(shù)據(jù)庫(kù)41,編譯程序42,以及建立處理43。數(shù)據(jù)庫(kù)41包括一組構(gòu)成部分,圖中所示為一個(gè)項(xiàng)目部件411和一個(gè)可建立的部件集412。該可建立的部件集合412成型為將被建立的一個(gè)程序。編譯程序42計(jì)算數(shù)據(jù)庫(kù)41的部件的相關(guān)性。建立處理43利用部件特性和編譯程序生成的相關(guān)性來建立該程序。
程序員可用編輯程序44改變?cè)摮绦?。編輯程序必須能夠生成及刪除這些部件,尤其是能夠進(jìn)行剪切、復(fù)制、粘貼和移動(dòng)這些部件。編輯程序必須可以改變“界面”和“實(shí)施”特性中的數(shù)據(jù),其方式通常是由對(duì)文本直接地進(jìn)行修改。然而,其他更為結(jié)構(gòu)化的途經(jīng)(例如從選項(xiàng)屏進(jìn)行選擇)亦可采用。實(shí)際上,編輯程序44通??梢园ǘ鄠€(gè)編輯程序,每個(gè)用于每種“界面”或“實(shí)施”特性,或甚至可能為特性中的數(shù)據(jù)的子區(qū)配置編輯程序。
寄存編輯改變的方法參見圖5A到圖5D,其中示出了與增量建立有關(guān)的編輯程序44所執(zhí)行的邏輯功能流程圖。對(duì)于可建立的非合成部件,“建立狀態(tài)”限于在建立處理之外的“編譯的值”和“需要編譯”值。若“界面”特性未出現(xiàn),則“界面建立狀態(tài)”是“編譯的”。若“實(shí)施”特性未出現(xiàn),則“實(shí)施建立狀態(tài)”是“編譯的”。圖5A中展示了各種編輯狀態(tài)變化。在500處,當(dāng)系統(tǒng)標(biāo)識(shí)了一個(gè)“生成部件”、“再命名部件”、“粘貼部件”、或’編輯界面”命令之時(shí),控制則進(jìn)到功能框510對(duì)界面變化進(jìn)行處理。該變化的詳細(xì)邏輯示于圖5B中。
圖5B中,處理始于判別框511,在該處,進(jìn)行測(cè)試以確定界面建立狀態(tài)是否為“需要編譯”。若是,則控制通過514進(jìn)行繼續(xù)編輯。這些動(dòng)作發(fā)生在編輯過程中而不是在建立過程中,下一動(dòng)作很可能是另一編輯動(dòng)作。若否,則在功能框512處把界面建立狀態(tài)設(shè)置成“需要編譯”并因此更新界面變化表。然后,在功能框5B處完成實(shí)施被改變和貯存器被改變的處理。實(shí)施被改變操作的細(xì)節(jié)示于圖5C中而貯存器被改變的操作細(xì)節(jié)示于圖5D中。
圖5C示出了與實(shí)施被改變有關(guān)的詳細(xì)過程。判別框571進(jìn)行測(cè)試以確定是否實(shí)施建立狀態(tài)已設(shè)定為“需要編譯”。若是,控制通過572進(jìn)行繼續(xù)編輯。若否,則在功能框573處把實(shí)施建立狀態(tài)設(shè)為等于“需要編譯”且實(shí)施變化表被因此而更新。然后,控制通過574返回。
圖5D示出了與貯存器改變操作有關(guān)的詳細(xì)邏輯。功能框542處將進(jìn)行測(cè)試以確定該變量是否為可建立。若是,則在功能框543處由部件的貯存器按圖5B討論的細(xì)節(jié)調(diào)用被改變的界面,然后,控制通過544返回。
若“編輯實(shí)施”命令在圖5A的560處被檢測(cè)到,則處理按照功能框570所示和圖5C的討論執(zhí)行實(shí)施被改變的動(dòng)作。
若在圖5A和530處檢測(cè)到“刪除部件”的命令,則用于部件A的貯存器被改變處理起始于功能框540,其細(xì)節(jié)示于圖5D中,然后,貯存器A被刪除且控制由550返回。
若在圖5A的580處檢測(cè)到一個(gè)“移動(dòng)”部件命令,則部件A的貯存器被改變處理起始于功能框590并詳細(xì)示于圖5D中。然后,部件的貯存器被設(shè)定于等于新的貯存器,且對(duì)于部件A的界面已改變的處理詳細(xì)示于圖5B中。最后,處理由595返回。
確定一個(gè)建立的組成部的方法在建立一個(gè)程序的過程中,“項(xiàng)目”組成部維持著稱之為編譯表的專用引用表。有一個(gè)“界面編譯表”和一個(gè)“實(shí)施編譯表”。“項(xiàng)目”還維持一個(gè)叫做“內(nèi)部錯(cuò)誤表”的專用引用表。實(shí)際上,這些表的每一個(gè)可由不止一個(gè)表實(shí)際地表示,以提高效率。
圖6展示的處理中,對(duì)于“項(xiàng)目”的“改變表”中的每個(gè)引用(如功能框601所示)從該表的前部選中一個(gè)引用。若在表上有多上引用,處理由框602所示完成。若引用是一個(gè)界面,如在框603所制定的,則將該引用的復(fù)制放在“界面編譯表”中并且在601繼續(xù)處理之前,在功能框604處把“加客戶(AddClients)”功能調(diào)用到該引用。若其特性名不是“界面”,則其特性名為“實(shí)施”,如框605所示,此時(shí),由判別框606進(jìn)行測(cè)試以確定是否為“在內(nèi)部”(IsInLine)屬性為真。若是,則將引用的復(fù)制放入“界面編譯表”并在框601的處理繼續(xù)之前在功能框607“界面編譯表”并在框601的處理繼續(xù)之前在功能框607處從該引用中調(diào)用“加客戶”功能。否則,其特性名肯定是“實(shí)施”且其“在內(nèi)部”屬性肯定為“假”,而且在框601的處理繼續(xù)之前,該引用的復(fù)制功能框608放在“實(shí)施編譯表”中。
“生成編譯表”功能的偽代碼如下
<pre listing-type="program-listing"><![CDATA[ CreateCompileLists( ){ for each A in ChangeList{ if(A.PropertyName==Interface){ InterfaceCompileList.Add(A); AddClients(A); } else if(A.PropertyName==Implementation){ if(IsInLine==True){ InterfaceCompileList.Add(A); AddClients(A); } else if(IsInLine==False){ ImplementationCompileList.Add(A); } } } }]]></pre>“加客戶”功能負(fù)責(zé)參數(shù)中每個(gè)引用,適當(dāng)?shù)匾蛻舨z查引用,并在其“建立狀態(tài)”被編譯時(shí),把該引參的“建立狀態(tài)”設(shè)為“不確定”,把該引用的復(fù)制加到適當(dāng)?shù)摹熬幾g表”,并在該引用中調(diào)用“加客戶”。這一處理稱為生成“改變表”的“客戶封閉(dient Closure)”。該“客戶封閉”表示需要作為一個(gè)建立的結(jié)果而被再次編譯的那些部件的子集。實(shí)際上,由建立過程的編譯程序生成的相關(guān)性及變化用于避免在“客戶封閉”中編譯過多的部件。
以下是“加客戶”的偽碼功能
<pre listing-type="program-listing"><![CDATA[ AddClients(A){ for each B in A.ClientList{ if(B.BuildState==Compiled){ B.SetBuildState(Uncertain); if(B.PropertyName==Interface){ InterfaceCompileList.Add(B); AddClients(B); } else if(B.PropertyName==Implementation){ ImplementationCompileList.Add(B); AddClients(B); } } } }]]></pre>處理“界面”的方法這是“建立”處理的第二階段。在“界面編譯表”用于項(xiàng)的可能的“建立狀態(tài)”是“已編譯”、“正被編譯”、“需要編譯”、“不確定”、“編譯錯(cuò)誤”或“不確定錯(cuò)誤”?!敖缑婢幾g表”被處理直到空了為止,如圖7的流程圖所示。處理始于701處,在該處,從“界面編譯表”的前部選中一個(gè)引用。如果在表上沒有更多的引用,便在框702處完成處理。如框703所示,若與該引用相關(guān)聯(lián)的構(gòu)成部分的界面“建立狀態(tài)”是已編譯的,“編譯錯(cuò)誤”或“不確定錯(cuò)誤”的,則從表的前部去除該引用并且在框701中繼續(xù)處理。若與該引用相關(guān)的構(gòu)成部分的界面“建立狀態(tài)”是“已被編譯”或“需要編譯”,如框704所示,則部件的“建立狀態(tài)”在框705中被設(shè)置為“已被編譯”。然后,在部件的“界面”調(diào)用“編譯”功能(它調(diào)用編譯程序42)。該功能將返回到“異常中止”值,“完成”值和“錯(cuò)誤”值之一。若在框706處返回“異常中止”值,則處理在框701處繼續(xù)。若返回框707的“完成”值,則部件的“界面建立狀態(tài)”被設(shè)為“編譯的”且在處理在框701處繼續(xù)之前,在框708處將把引用從表的前部去除掉。若返回的值是框709處的“錯(cuò)誤”,則該部件的“界面建立狀態(tài)”設(shè)定為“編譯錯(cuò)誤”,從表的前部去掉該引用,并在701處繼續(xù)處理之前,在功能框710中的部件調(diào)用“傳播錯(cuò)誤”功能。若與該引用相關(guān)聯(lián)的“界面建立狀態(tài)”為“不確定”,如框711所示,則該部件的“建立狀態(tài)”在功能框712處設(shè)為“已被編譯”。然后在該部件的“界面”上調(diào)用“有條件地編譯”功能(可以調(diào)用也可以不調(diào)用編譯程序42)。該功能也返回到“異常中止”值,“完成”值和“錯(cuò)誤”值之一。若返回到“異常中止”值,則在步驟701處的處理繼續(xù)進(jìn)行。若返回到框713處的“完成”值,則在功能框708中從表的前部去掉該引用并繼續(xù)進(jìn)行框701處的處理。若返回框714處的“錯(cuò)誤”值,則從表的前部去掉該引用并在框701的處理繼續(xù)進(jìn)行之前,在功能框715中的部件里調(diào)用該“傳播錯(cuò)誤”功能。
用于“處理界面”功能的偽碼如下<pre listing-type="program-listing"><![CDATA[ProcessInterfaces( ){ until((A=InterfaceCompileList.First)==NIL){ state=A.BuildState; if(A=Compiled_CompileError_Uncertainerror){ InterfaceCompileLrst.RemoveFirst( ); } else if(A=BeingCompiled_NeedToCompile){ A.SetBuildState(BeingCompiled); value=Compile(A); if(value==Abort){ continue; } else if(value==Done){ A.SetBuildState(Compiled); InterfaceCompileList.RemoveFirst( ); } else if(value==Error){ A.SetBuildState(CompileError); InterfaceCompileList.RemoveFirst( ); PropagateError(A); } } else if(A=Uncertain){ A.SetBuildState(BeingCompiled); value=ConditionallyCompile(A); if(value==Abort){ continue;} else if(value==Done){ A.SetBuildState(Compiled); InterfaceCompileList.RemoveFirst( ); } else if(value==Error){ A.SetBuildState(UncertainError); InterfaceCompileList.RemoveFirst( ); PropagateError(A); } } }}]]></pre>
“傳播錯(cuò)誤”功能是把一個(gè)與部件對(duì)應(yīng)的引用加到“項(xiàng)目”的“內(nèi)部錯(cuò)誤表”中并對(duì)部件的“客戶”表中的每個(gè)引用執(zhí)行如下若該引用的“建立狀態(tài)”是“編譯錯(cuò)誤”或“不確定錯(cuò)誤”,處理繼續(xù)下一個(gè)引用。若該引用的“建立狀態(tài)”是“需要編譯”,處理把它的“建立狀態(tài)”設(shè)為“編譯錯(cuò)誤”,并將引用把加到“內(nèi)部錯(cuò)誤表”,并在繼續(xù)下一引用之前為引用調(diào)用“傳播錯(cuò)誤”。若引用的“建立狀態(tài)”為“不確定”,則處理把其“建立狀態(tài)”設(shè)到“不確定錯(cuò)誤”,把引用加到“內(nèi)部錯(cuò)誤表”,并在繼續(xù)下一引用之前在引用上調(diào)用“傳播錯(cuò)誤”。
“傳播錯(cuò)誤”功能的偽碼如下<pre listing-type="program-listing"><![CDATA[ PropagateError(A){ for each B in A.ClientList{ state=B.BuildState; if(state==CompileError_UncertainError)[ continue; } else if(state==NeedToCompile){ B.SetBuildState(CompileError){ InternalErrorList.Add(B); PropagateError(B); } else if(state==Uncertain){ B.SetBuildState(UncertainError); InternalErrorList.Add(B); PropagateError(B);} } }]]></pre>處理“實(shí)施”的方法這是“建立”處理的第三階段,如圖8的流程圖所示,在“實(shí)施編譯”表中的每個(gè)引用都被處理。該處理始于801處,在該處,從實(shí)施編譯表的前部選中一個(gè)引用。若無更多的引用,在框802處完成處理。若該引用的“建立狀態(tài)”為“不確定”,如框803所示,則在框801繼續(xù)處理之前在功能框804中把“建立狀態(tài)”設(shè)置為“已編譯的”。若該引用的“建立狀態(tài)”是“需要編譯”,如框805所示,則在功能框806處編譯該部件。從編譯程序42返回的值可能是“完成”和“錯(cuò)誤”。若在框807處返回值是“完成,則在框801繼續(xù)處理之前,在功能框804中把該引用的“建立狀態(tài)”設(shè)為“已編譯的”。若把框808中返回的值為“錯(cuò)誤”,則將該引用的“建立狀態(tài)”設(shè)定為“編輯錯(cuò)誤”并在框801繼續(xù)處理之前,在功能框809的部件中調(diào)用“傳播錯(cuò)誤”功能。若該引用的’建立狀態(tài)”是“編譯錯(cuò)誤”或“不確定錯(cuò)誤”,將不作任何事。應(yīng)注意,“實(shí)施”的處理在這一階段順序獨(dú)立的,因?yàn)橄嚓P(guān)性只可以在其內(nèi)部屬性是“真”而且已被處理過的“界面”或“實(shí)施”中。
“處理實(shí)施”的偽碼如下
<pre listing-type="program-listing"><![CDATA[ProcessImplementations( ){ for each A in ImplementationCompileList{ state=A.BuildState; if(A=Uncertain){ A.SetBuildState(Compiled); } else if(A=NeedToCompile){ value=Compile(A); if(value==Done){ A.SetBuildState(Compiled); } else if(value==Error){ A.SetBuildState(CompileError); PropagateError(A); } } else if(A=CompileError_UncertainError){ } }}]]></pre>
支持建立處理的編譯程序編譯程序42通過“編譯”功能而被調(diào)用,兩者亦可作為替代命令使用。編譯程序42處理源文本并標(biāo)識(shí)可能的外部部件的名字。編輯程序42下一步獲取所有部件的引用表。該編輯程序可用語言專用知識(shí)(例如部件類別)從該表中刪除這些引用。編譯程序然后為文本標(biāo)識(shí)的每個(gè)外部部件調(diào)用“獲得說明(GetDealaration)”功能。在調(diào)用編譯程序之前,該“編譯”功能清除一切現(xiàn)存的錯(cuò)誤。這也將清除任何來自“錯(cuò)誤”特性的錯(cuò)誤消息并從“項(xiàng)目”的的“錯(cuò)誤表”特性中去除任何引用。
編譯程序首先調(diào)用“獲得說明”功能,如圖9的流程圖所示?!矮@得說明”功能返回到“異常中止”值、“完成”值、“循環(huán)相關(guān)性”值或“錯(cuò)誤”值的其中之一,并可返回“說明”的數(shù)據(jù)。處理起始于框901,在該處,每個(gè)引用的“建立狀態(tài)”被檢查。若沒有更多的引用要處理,便在框920處完成處理并返回。若該部件的“建立狀態(tài)”在框903處為“編譯的”,則功能返回到“完成”,如框904所示,而且在框901繼續(xù)處理之前,存儲(chǔ)的“說明”數(shù)據(jù)也被返回。若部件的“建立狀態(tài)”在框905處示為“需要編輯”或“不確定”,則相應(yīng)于該部件的引用在功能框906中被加到“界面編譯表”的前部,并在框901繼續(xù)其處理之前,該功能返回到功能框907的“異常中止”。“說明”數(shù)據(jù)在這一情況下不返回,若部件的“建立狀態(tài)”為框908所示的“被編輯”,則在框901繼續(xù)處理之前,功能將去往功能框909處的“循環(huán)相關(guān)性”?!罢f明”數(shù)據(jù)在這一情況下亦不返回。若部件的“建立狀態(tài)”是框910所示的“編輯錯(cuò)誤”或“不確定錯(cuò)誤”,則在框901繼續(xù)其處理之前,功能返回到功能框911的“錯(cuò)誤”。在這種情況下亦無“說明”數(shù)據(jù)返回。
“獲得說明”功能的偽碼如下<pre listing-type="program-listing"><![CDATA[ value GetDeclaration(A,Declaration){ Declaration=NIL; state=A.BuildState; if(state==Compiled){ Declaration=CurrentDeclaration( ); return(Done); } else if(state==NeedToCompile_Uncertain){ InterfaceCompileList.AddToFront(A); return(Abort); } else if(state==BeingCompiled){ return(Circulardependency); } else if(state==CompileError_UncertainError){ return(Error); } }]]></pre>
在調(diào)用“獲得說明”功能之后,編譯程序繼續(xù)進(jìn)行如下的過程。若返回值為“異常中止”,則編輯程序必須中止處理并返回到“異常中止”值。一個(gè)替代實(shí)施方案是要編譯程序在編譯該返回的部件之后,中止編譯,放棄或重新啟動(dòng)編輯程序。這會(huì)要求編譯程序再次進(jìn)入。但若不是這樣的話,就不會(huì)有上述的重大變化。若返回的值是“編譯的”,則編譯程序可繼續(xù)其處理。若采用“說明”,則將構(gòu)成“源引用相關(guān)性”,而且編譯程序會(huì)保持追蹤相關(guān)性及其性質(zhì)。若返回值是“循環(huán)相關(guān)性”或“錯(cuò)誤”,則編譯程序必須中止處理。在部件上調(diào)用“設(shè)置錯(cuò)誤(Set Error)”功能,并返回“錯(cuò)誤”值。編譯程序可以選擇繼續(xù)處理以便在結(jié)束之前發(fā)現(xiàn)更多可能的錯(cuò)誤。
若對(duì)“獲得說明”的調(diào)用返回到“編譯的”,則編譯程序?qū)⒁猿R?guī)方式繼續(xù)處理源文本。若在處理過程中遇到任何錯(cuò)誤,編輯程序?qū)⒄{(diào)用部件的“設(shè)置錯(cuò)誤”功能并返回“錯(cuò)誤”值,若沒有遇到錯(cuò)誤,則編譯程序返回“完成”值。若編譯程序已經(jīng)在對(duì)一個(gè)界面進(jìn)行處理,則它將存貯該“說明”特性的新值。
處理“錯(cuò)誤”的方法在編譯程序被調(diào)用以編譯一個(gè)“界面”或“實(shí)施”之前,清除所有現(xiàn)有的“錯(cuò)誤”。這將保證所有的錯(cuò)誤消息被更新。由于“界面”和“實(shí)施”之前的內(nèi)部相關(guān)性以及這樣的事實(shí),即錯(cuò)誤是可傳播的,所以將不可能在同一建立上在“界面”和“實(shí)施”上同時(shí)得到編譯程序錯(cuò)誤。
當(dāng)編譯程序遇到錯(cuò)誤時(shí),它調(diào)用傳送與錯(cuò)誤有關(guān)的信息的功能“設(shè)置錯(cuò)誤”,該信息包括錯(cuò)誤的位置,以及描述錯(cuò)誤的消息和返回到的錯(cuò)誤組成部。該信息存儲(chǔ)在“錯(cuò)誤”特性和部件的正確源特性(“界面”或“實(shí)施”)之中。一個(gè)引用也存在允許對(duì)所有錯(cuò)誤進(jìn)行方便地存取的“項(xiàng)目”所維護(hù)的總錯(cuò)誤表中。
錯(cuò)誤將傳播到任意相關(guān)部件以便這些部件無需在其后被編譯。因?yàn)檫@些編譯已知將會(huì)失敗。進(jìn)而,遇到錯(cuò)誤后將繼續(xù)建立并盡可能多正確建立那些本身并無明顯錯(cuò)誤的部件或與錯(cuò)誤部件有關(guān)聯(lián)的部件。
“設(shè)置錯(cuò)誤”功能獲取由編輯程序42傳給它的錯(cuò)誤消息并在相應(yīng)于適當(dāng)特性(“界面”或“實(shí)施)的部件的“錯(cuò)誤”特性中生成一個(gè)入口,它還在與該錯(cuò)誤對(duì)應(yīng)的“項(xiàng)目”的“錯(cuò)誤表特性”中生成一個(gè)入口。以這一方式生成的兩個(gè)入口共享同一鍵,以致它們保持“連接”。這一功能通常還用一個(gè)“粘性標(biāo)志”把錯(cuò)誤的位置記錄在程序源之中。該“粘性標(biāo)志”在稍后的用戶編輯過程中一直附屬到字符的相同范圍。
若編譯程序成功地完成了源文本的處理,則其將產(chǎn)生目標(biāo)碼并將其通過“連接程序”功能進(jìn)行增量連接。而且,目標(biāo)碼可存到建立處理結(jié)束并以常規(guī)方式連接。
編譯程序現(xiàn)在將更新部件的“源引用(SourceRefRerence)1特性以及每個(gè)“源引用”的“客戶”特性。對(duì)每一個(gè)引用,例如部件A的“源引用”特性中的部件B,將必須有一與部件B的“客戶”特性中的部件A相對(duì)應(yīng)的引用(它具有同樣的相關(guān)性信息)。
編輯程序?qū)⑸梢粋€(gè)“變化”以描述“說明”如何從其當(dāng)前值改變的,編輯程序?qū)⒃诓考险{(diào)用傳播改變(PropagateChange)功能并把計(jì)算出來的改變傳播給該部件。該編譯程序然后將設(shè)定“說明”的新值。“傳播改變”的功能與針對(duì)部件的“客戶”表中的每個(gè)引用的相關(guān)性的變化吻合。若該吻合指示引用的部件已為改變所影響,且其“建立狀態(tài)”不是“編譯錯(cuò)誤”或“不確定錯(cuò)誤”,則其“建立狀態(tài)”設(shè)為“需要編譯”。
有可能要編譯程序使用“設(shè)置錯(cuò)誤”功能以發(fā)布告警信息或不同格式的建議。在這種情況下,若只有告警信息返回,則“編譯”功能應(yīng)返回到“完成”。告警信息將被加到“錯(cuò)誤”特性且引用將被加到“項(xiàng)目錯(cuò)誤表”特性。否則編譯將被認(rèn)為是成功的。適當(dāng)?shù)摹敖顟B(tài)”將被設(shè)置為“編輯的”,而且將無錯(cuò)誤被傳播。若只發(fā)布了告警或建議,則程序?qū)⒈煌耆丶罢_地建立。
“有條件地編譯”一個(gè)部件的處理圖10A和10B示出了“有條件編譯”功能的流程圖,其中進(jìn)行了引用,在部件的“源引用用”中的每個(gè)部件B在框1001處進(jìn)行處理。則對(duì)部件B的處理結(jié)束而處理去往圖10B以編譯組成部件A。部件B的“建立狀態(tài)”是“被編譯”或“需要編譯”,如框1003所示,則該部件的“建立狀態(tài)”被設(shè)定為“被編譯”且該部件在功能框1004中被編譯。該編譯功能可以返回到“完成”值,“異常中止”值和“錯(cuò)誤”值其中之一。若返回框1005的“完成”值,處理將繼續(xù)在框1001處進(jìn)行。
若返回值是框1006的“異常中止”,則功能中止且“異常中止”返回到框1007。若返回值是框1008中的“錯(cuò)誤”,則原始部件的“建立狀態(tài)”被設(shè)置為“不確定錯(cuò)誤”,功能被停止且“錯(cuò)誤”返回到功能框1009中。若部件B的“建立狀態(tài)”是“不確定”,如框1010所示,則“建立狀態(tài)”被設(shè)定為“被編譯”且該部件在功能框1011中被有條件地編譯。再一次,“有條件地編譯”功能可以返到“完成”,“異常中止”或’錯(cuò)誤”值之一。若“完成”值返回框1005,處理在框1001處繼續(xù)。若“錯(cuò)誤”返回到框1012,則部件的“建立狀態(tài)”被設(shè)為“不確定錯(cuò)誤”,從“界面編譯表”中去除部件A,并在功能結(jié)束之前在功能框1014中調(diào)用“傳播錯(cuò)誤”功能。若返回框1015的“異常中止”,則在功能結(jié)束之前“異常中止”返回框1007。
現(xiàn)在再來看圖10B,若所有引用已被處理過,則它們的“建立狀態(tài)”都是“編譯的”。但是,“源引用”之一可能在對(duì)這一點(diǎn)的處理過程中已經(jīng)把一個(gè)變化傳播到部件,所以它的“建立狀態(tài)”可以是“被編譯”或“需要編譯”。因此,部件A的“建立狀態(tài)”在框1016中決定。若框1017處指出該“建立狀態(tài)”是“需要編譯”,則該“編譯狀態(tài)”被設(shè)定為“被編輯”且部件A在功能框1018中被編譯。編譯程序可返回到“錯(cuò)誤”或“完成”。注意“異常中止”不會(huì)發(fā)生,因?yàn)樗械摹匆谩倍荚谶@一階段被編譯了。若“錯(cuò)誤”去往框1019,則“建立狀態(tài)”設(shè)為“編譯錯(cuò)誤”而且“錯(cuò)誤”返回到功能框1020。若“完成”去往框1021,則“建立狀態(tài)”設(shè)為“編譯的”且“完成”去往功能框1023。若部件A的“建立狀態(tài)”是“被編譯”,如框1024所示,則“建立狀態(tài)”被設(shè)為“編譯的”而且“完成”去往功能框1023。
“有條件地編譯”功能的偽碼如下<pre listing-type="program-listing"><![CDATA[ value ConditionallyCompile(A){ for each B in A.SourceReference{ state=B.BuildState; if(state==NeedToCompile_BeingCompiled){ B.SetBuildState(BeingCompiled); value=Compile(B); if(value==Done){ continue; } else if(value==Abort){ return(Abort); } else if(value==Error){ A.SetBuildState(UncertainError); return(Error); } }else if(state==Uncertain); A.SetBuildState(BeingCompiled); value=ConditionallyCompile(A); if(value==Done){ continue; } else if(value==Abort){ return(Abort); } else if(value==Error){ A.SetBuildState(UncertainError); InterfaceCompileList.Remove(A); PropagateError(A); } } }state=A.BuildState;if(state==NeedToCompile){ A.SetBuildState(Being Compiled); value=Compile(A); if(value==Done){ A.SetBuildState(Compiled); return(Done); }elseif(value==Error){ A.SetBuildState(CompileError); return(Error); } } A.SetBuildState(Compiled); return(Done); } }]]></pre>后處理錯(cuò)誤的方法后處理錯(cuò)誤的方法是“建立”處理的第四階段。若在建立過程中發(fā)生了任何錯(cuò)誤,則“后處理錯(cuò)誤”(PostPro-cessingErrors)功能便在建立結(jié)束時(shí)被調(diào)用。對(duì)每個(gè)在“內(nèi)部錯(cuò)誤表”中的引用而言,若引用的“建立狀態(tài)”是“編譯錯(cuò)誤”,則“建立狀態(tài)”改變成“需要編譯”,若引用的“建立狀態(tài)”是“不確定錯(cuò)誤”,則“建立狀態(tài)”被改變?yōu)椤耙丫幾g的”。
當(dāng)所有在“內(nèi)部錯(cuò)誤表”上的引用已處理完畢后,該表的所有入口被消除。為便于程序員,若“項(xiàng)目”的錯(cuò)誤表包含任何入口,則將在“項(xiàng)目”的“錯(cuò)誤表”上開一個(gè)視窗或?yàn)g覽窗。
“后處理錯(cuò)誤”功能的偽碼如下<pre listing-type="program-listing"><![CDATA[ PostProcessErrors( ){ for each A in InternalErrorList{ state=A.BuildState; if(state==CompileError){ A.SetBuildState(NeedToCompile); } else if(state==UncertainError){ A.SetBuildState(Compiled); } } InternalErrorList.ClearAll( ); if(ErrorList.Count!=0){ OpenErrorWindow( ); } }]]></pre>使用面向人的目標(biāo)編程系統(tǒng)(HOOPS)根據(jù)本發(fā)明的面向人的目標(biāo)編程系統(tǒng)(HOOPS)可通過進(jìn)入一個(gè)項(xiàng)目名或現(xiàn)有的項(xiàng)目名來從計(jì)算機(jī)開始,這要取決于是否要建立新的程序或建立現(xiàn)存的程序。當(dāng)HOOPS開始時(shí),視窗被打開并顯示一個(gè)與圖11所示屏幕類似的初始屏面。該HOOPS打開的初始視窗顯示了“項(xiàng)目”部件的“成員”特性以及其直接成員。雖然它初始只顯示了直接成員,但同樣的視窗用于顯示始于項(xiàng)目部件處的每個(gè)部件。在圖11的示例中,一個(gè)叫做“工資單(Pagroll)”的“項(xiàng)目”已被輸入。
窺視窗窺視窗是用于顯示一個(gè)部件特定特性的圖形展示。但是,在顯示該特性的處理過程中,可能會(huì)要求窺視窗顯示輔助信息,它們包括從其他特性而來的數(shù)據(jù)。一個(gè)窺視窗有一輸入和輸出。該輸入指至少一個(gè)部件和特性,也可以指定該特性的信息的子范圍。該輸出至少指一個(gè)部件。它亦可指定一個(gè)特性以及該特性數(shù)據(jù)的一個(gè)子范圍。該輸出可響應(yīng)于用戶操作及系統(tǒng)中的狀態(tài)變化而隨時(shí)改變。
窺視窗表是一個(gè)窺視窗說明的命名表,其中,每個(gè)說明定義一個(gè)窺視窗名字及實(shí)施分類。有一個(gè)叫做空窺視窗表的區(qū)別窺視窗表,它不包含窺視窗說明。窺視窗表名字與每個(gè)特性關(guān)聯(lián)。特性可以被表中指定的任意窺視窗顯示。若一個(gè)特性與空窺視窗表關(guān)聯(lián),則不會(huì)有該特性的窺視窗,而且該特性被認(rèn)為是不可顯示的。一個(gè)最佳窺視窗將與每個(gè)特性關(guān)聯(lián)該最佳窺視窗必須在與特性相關(guān)聯(lián)的窺視窗表中指定的窺視窗之中。一個(gè)最佳特性與要被窺視的部件關(guān)聯(lián)。
窗格(Paue)一個(gè)窺視窗顯示在一窗格中。窗格有一輸入和輸出。該輸入指定至少一個(gè)部件。它亦可指定部件的一個(gè)特性和特性的數(shù)據(jù)的一個(gè)子范圍。其輸出指定至少一個(gè)部件并可指定一個(gè)特性和該特性數(shù)據(jù)的一個(gè)子范圍。該輸出可響應(yīng)用戶動(dòng)作及系統(tǒng)內(nèi)的狀態(tài)改變而隨時(shí)改變。
一個(gè)窗格確定了它的窺視窗輸入,該輸入一般是從該窗格的輸入中導(dǎo)出而來的。它可動(dòng)態(tài)地根據(jù)系統(tǒng)狀態(tài)或靜態(tài)地改變窗格的實(shí)施而從窗格到窗格進(jìn)行變化。在最簡(jiǎn)導(dǎo)出中,窺視窗的輸入與窗格的輸入相等。類似地窗格的輸出來自于對(duì)窺視窗格輸出的導(dǎo)出。該求導(dǎo)出的性質(zhì)從窗格到窗格不同,它或者動(dòng)態(tài)地取決于系統(tǒng)狀態(tài),或者靜態(tài)地由窗格實(shí)施的變化而定。在最簡(jiǎn)導(dǎo)出中,一個(gè)窗格的輸出等于其窺視窗的輸出。
視窗窗格顯示于視窗之中。視窗被細(xì)分為一個(gè)或多個(gè)窗格。在一個(gè)視窗中的窗格數(shù)量及大小可由用戶動(dòng)態(tài)地控制。一個(gè)最佳實(shí)施例在每個(gè)窗格中提供窗格劃分程序控制以簡(jiǎn)化多窗格的生成和管理。該控制用于把一個(gè)單個(gè)的窗格分為一個(gè)或多個(gè)窗格。
圖12示出了根據(jù)本發(fā)明的一個(gè)瀏覽窗。在HOOPS中的每個(gè)視窗都是瀏覽窗。瀏覽窗是暫時(shí)可見的和編輯工具,用于查看“項(xiàng)目”中的信息。只要在視窗中的關(guān)閉圖符1210上按一下,即可在任意時(shí)刻刪除瀏覽窗。任何在測(cè)覽窗中對(duì)“項(xiàng)目”所做的改變都被自動(dòng)保存起來。一個(gè)瀏覽窗有一個(gè)項(xiàng)目根部件1200,它在打開時(shí)被指定。一個(gè)存貯器部件的實(shí)例展示于1202處,一個(gè)選擇的部件示于1203處,一個(gè)窗格特性上托選擇屏控制1220以及一個(gè)擴(kuò)展或壓縮控制示于1204。該控制可使用戶把一個(gè)窗格導(dǎo)向一個(gè)特定的特性。輸入部件的特性2130在窗格1260中顯示。而且每個(gè)窗格1260顯示一個(gè)特性窺視窗1205或是空白的,如1260所示。新窗格由在一個(gè)窗格右上角中選擇一個(gè)劃分圖符1250的方式而加到一個(gè)瀏覽窗中。窗格劃分控制1250允許用戶將一個(gè)窗格分為兩個(gè)并控制其幾何尺寸。也有一個(gè)窗格和測(cè)覽窗放大/縮小框1242和1243,它們使得用戶可以動(dòng)態(tài)地放大/縮小一個(gè)窗格以使完全充滿視窗,并使得用戶將窗格恢復(fù)至其原有尺寸。水平和垂直卷動(dòng)控制1252被提供以便卷動(dòng)位于一個(gè)窗格中的窺視窗。窗格標(biāo)題框1241顯示部件的名字及由該窗格顯示的特性。窺視窗選項(xiàng)屏1251提供用于使用戶選擇用于顯示選定特性的窺視窗。
綜合考慮三個(gè)因素,以使確定由一個(gè)窗格顯示的專用窺視窗。它們是部件,該部分的特性,以及該特性的窺視窗。部件由窗格的輸入導(dǎo)出而來。特性亦來自對(duì)窗格的導(dǎo)出,或來自一個(gè)用戶的替換。若該窗格輸入指定了輸入部件的一個(gè)專用特性,則該特性按該特性關(guān)聯(lián)的窺視窗表所定義的來確定一組合格的窺視窗。若該窗格輸入未指定一個(gè)特性,則將被顯示的特性是部件的系統(tǒng)設(shè)定特性。
用戶可以通過選擇用于觀察或把一個(gè)窗格固定到一專用特性的另一輸入部件特性的方式而替換選定的特性。當(dāng)固定后,該窗格顯示固定的特性而與輸入部件無關(guān)。當(dāng)一個(gè)窗格的部件或特性變化時(shí),一個(gè)新窺視窗在該窗格中顯示。該窺視窗是特性的系統(tǒng)設(shè)定窺視窗;然而,用戶可以順序改變?cè)摳Q視窗成為在與顯示特性關(guān)聯(lián)的窺視窗表中列出任何項(xiàng)。
當(dāng)生成一個(gè)新窗格時(shí),系統(tǒng)設(shè)置的“連線(Wiring)”從分裂成新方格的方格中生成。“連線”是在一個(gè)窗格之間的邏輯關(guān)系。一個(gè)窗格可以有零個(gè)或一個(gè)連線輸入及零個(gè)或多個(gè)連線作為輸出,但連線不可以形成回路。當(dāng)在一個(gè)窗格中選擇了一個(gè)部件時(shí),該選擇被轉(zhuǎn)換成對(duì)項(xiàng)目中部件的一個(gè)引用并成為一個(gè)對(duì)來自該窗格的任何連線的目的的新輸入。通過從選項(xiàng)屏條選擇的瀏覽窗選項(xiàng)屏中的“Turn on Wiring”(接通連線)可接通連線,從而產(chǎn)生圖13的疊加圖形連線的顯示。采用這一顯示,可能通過在新輸入位置按下鼠標(biāo)器并將其拉至目標(biāo)窗格的方式改變兩個(gè)窗格之間的連線。
在許多窺視窗中(例如“成員”,“客戶”以及“引用”),部件可由它們的名字以及圖符(它們由部件類別區(qū)分)所區(qū)別,在其他窺視窗中,一個(gè)部件的名字只出現(xiàn)在本文中,例如在“源”或“資料”中部件層次可由擴(kuò)展和縮滅在“成員”特性窺視窗中的貯存器部件從而產(chǎn)生一個(gè)“樹”視圖的方式進(jìn)行測(cè)覽,圖14便展示了該例子。一個(gè)部件的子樹的一級(jí)可通過按一下部件的循環(huán)雙態(tài)開關(guān)的方式加以擴(kuò)散或縮滅。當(dāng)通過按一下圖符或在文本顯示中選擇其名字的方式在一個(gè)窺視窗中選擇一個(gè)部件時(shí),在總選項(xiàng)屏條中的“特性”選擇屏被調(diào)整以列出部件的類型。任何部件的任何特性可以通過在一個(gè)窺視窗中選擇該部件并然后從“特性(Property)”選項(xiàng)屏中選中一個(gè)特性的方式進(jìn)行視查。這會(huì)打開一個(gè)包括一個(gè)窺視窗的新瀏覽窗,該窺視窗顯示選定部件的選中特性。
通過指定任何處生成新部件以及該部件類別,可在一個(gè)“成員”或“界面”窺視窗中生成部件。該新部件的位置由選擇一個(gè)現(xiàn)有的部件或在部件之間放入一插入點(diǎn)的方式而予指定。生成的部件的類別通過從“New”窺視窗選項(xiàng)屏中選擇選項(xiàng)屏項(xiàng)所決定。所有編輯都自動(dòng)存儲(chǔ)。只有已改變的部件以及受改變所影響的客戶才被編譯。重新編譯的部件可通過從“Build”選項(xiàng)屏中選中的“Show Components Build”選項(xiàng)屏項(xiàng)進(jìn)行觀看。為了觀看從最后建立以來的改變的部件,要從“Build”選項(xiàng)屏中選擇“Sleow Compenents Changed”。通過從“Build”選項(xiàng)屏中選擇“Build”,可對(duì)一個(gè)程序進(jìn)行編譯和連接?!癇uild & Run”選項(xiàng)屏也運(yùn)行該程序。
圖15至18展示了在編輯一個(gè)部件的處理過程中顯示的一些屏面。圖15示了一個(gè)“main”功能的“實(shí)施”的源碼顯示。在圖16中,功能“main”已由把“numberDisks”從“7”改變“9”的方式進(jìn)行了編輯。若程序員現(xiàn)在從圖17中示出的“Build”選項(xiàng)屏中選擇“Show Components Changed”則圖18所示的瀏覽窗便會(huì)出現(xiàn)。在“Implementation Changes”窺視窗中(在右側(cè)),功能“main”被顯示,指示改變已發(fā)生。
面向目標(biāo)連接本敘述列出了HOOPS連接程序的重要特性,它提供了一個(gè)最佳實(shí)施例的運(yùn)行時(shí)間環(huán)境的背景以及提供連接出現(xiàn)的上下文的HOOPS數(shù)據(jù)庫(kù)。最后,有關(guān)HOOPS編譯程序HOOPS數(shù)據(jù)庫(kù),以及系統(tǒng)裝入程序的連接和交互的討論將參照一個(gè)最佳實(shí)施例進(jìn)行。
連接程序特性·連接發(fā)生在編譯處理過程中,沒有其它的連接通路。
·在建立過程中,只有最新被編譯的功能和數(shù)據(jù)才被再次連接。
·在增量發(fā)展過程中,某些共享的庫(kù)空間被用于換取速度。
·編譯程序與部件和特性交互以產(chǎn)生全部目標(biāo)碼和其他連接信息。
·當(dāng)一個(gè)程序可交付使用時(shí),一個(gè)“出版”步驟將去除增量發(fā)展過程中用過的多余的空間和信息,并程序與HOOPS分離開。
·一個(gè)“快速出版(QuickPublish)”步驟將從用于與其他程序共享的HOOPS中把該程序快速地分離出來,或移至另一機(jī)器。
·連接程序可是擴(kuò)充的,因?yàn)樵摼幾g程序可以指定該連接程序通常不處理的新安排。
·一個(gè)中止的程序可被修改然后再恢復(fù)執(zhí)行而無須被再次裝入(有些變化將要求裝入)。
連接程序在HOOPS內(nèi)操作并生成由裝入程序使用的文件。為了理解連接程序技巧,重要的是要理解運(yùn)行時(shí)間系統(tǒng)和HOOPS的獨(dú)特之處。
一個(gè)可執(zhí)行的文件與運(yùn)行時(shí)間的交互在其他運(yùn)行時(shí)間系統(tǒng)中大不相同。通常,一個(gè)裝入程序必須理解可執(zhí)行文件格式。該可執(zhí)行文件已知描述該程序各個(gè)方面(例如所需存儲(chǔ)器量,主地址,任何在裝入時(shí)刻需要的再定位信息,以及任何在可執(zhí)行文件中組裝的調(diào)試信息)的字段。在一個(gè)最佳實(shí)施例的運(yùn)行時(shí)間中,裝入程序通過一個(gè)抽象“T裝入模塊(TLaodModule)”分類界面與該可執(zhí)行文件交互。該“T裝入模塊”為所有裝入操作提供協(xié)議,例如,象指定存儲(chǔ)器要求,建立元數(shù)據(jù)信息以及連接其他共用庫(kù)的操作都由“T裝入模塊”的方法提供。借助這一方式,一個(gè)裝入模塊可以有許多方式響應(yīng)裝入請(qǐng)求。
運(yùn)行時(shí)間定義提供了共用庫(kù),并允許在裝入時(shí)刻解決交叉庫(kù)調(diào)用。由于庫(kù)可以在任何存儲(chǔ)位置裝入,所有碼必須是位置獨(dú)立的,或必須在裝入時(shí)刻被修補(bǔ)。除了位置獨(dú)立碼之外,必須在裝入時(shí)刻解決對(duì)其他庫(kù)的調(diào)用。這是由于靜態(tài)連接程序不知道存儲(chǔ)器中的外部庫(kù)的定位或相對(duì)位移是什么。
雖然每個(gè)“T裝入模塊”分類可以許多不同方式實(shí)施交叉庫(kù)調(diào)用,標(biāo)準(zhǔn)方式則是要通過在裝入時(shí)刻修補(bǔ)過的連接區(qū)轉(zhuǎn)移,該連接區(qū)作為在兩個(gè)庫(kù)之間的間接轉(zhuǎn)移表。一個(gè)外部調(diào)用將轉(zhuǎn)移子程序返回(JSR)到該連接區(qū),然后該連接區(qū)將轉(zhuǎn)移(JMP)到調(diào)用的功能。內(nèi)部調(diào)用可以直接轉(zhuǎn)移并程序返回到該調(diào)用的功能。一個(gè)內(nèi)部和交叉庫(kù)調(diào)用的實(shí)例示于圖19中并說明如下。
對(duì)f1( )1900的調(diào)用是一個(gè)內(nèi)部調(diào)用,所以JSR直接去往f1( )1910。對(duì)f2( )1920的調(diào)用是一個(gè)交叉庫(kù)調(diào)用,因此調(diào)用去往裝入時(shí)刻修補(bǔ)的外部連接區(qū)1930。
HOOPS環(huán)境還提供了連接程序的唯一的上下文聯(lián)系。一個(gè)程序被展示為一個(gè)部件集合。每個(gè)部件有一組相關(guān)的特性。在每個(gè)部件的編譯過程中,編譯程序?qū)⑸珊痛鎯?chǔ)用于該部件的特性。HOOPS建立處理對(duì)部件的建立排序,以致于所有界面說明在實(shí)施(定義)之前便被編譯。
一個(gè)HOOPS項(xiàng)目可以包括幾個(gè)庫(kù)部件。所有源部件都是這些庫(kù)部件之一的成員。每個(gè)庫(kù)部件表示一個(gè)共用庫(kù)建立。
綜觀為了支持增量連接并使最終應(yīng)用程序成為最小最快,生成了兩種不同的裝入模塊。在開發(fā)過程中,HOOPS生成和修改了一個(gè)“T增量裝入模塊(T incremental Load Module)”。有一個(gè)第二文件,“T標(biāo)準(zhǔn)裝入模塊(TStfandardLoadModule)在出版應(yīng)用程序之前生成。
一個(gè)最佳實(shí)施例公開了在開發(fā)過程中建立和更新代碼的途徑。把一個(gè)“T增量裝入模塊”轉(zhuǎn)換成“T標(biāo)準(zhǔn)裝入模塊”涉及一個(gè)多余的“出版”步驟。該步驟與一個(gè)常規(guī)的連接步驟很類似,其中,每個(gè)功能或數(shù)據(jù)項(xiàng)將被再定位和修補(bǔ)。但是,直到裝入時(shí)刻才解決外部引用。
編譯程序交互隨著編譯程序生成一個(gè)部件的代碼,該碼由用于修補(bǔ)目標(biāo)碼的一組安排傳到目標(biāo)碼特性。每個(gè)編譯的部件使其目標(biāo)碼特性裝滿。編譯程序使用一個(gè)“目標(biāo)組”模塊。即一個(gè)部件可以由多種類型的目標(biāo)碼組成。例如,一個(gè)功能可能也有一個(gè)與其相關(guān)的專用靜態(tài)數(shù)據(jù)區(qū)以及用于該靜態(tài)數(shù)據(jù)區(qū)的解除程序順序。一個(gè)靜態(tài)數(shù)據(jù)項(xiàng)可能有一個(gè)構(gòu)成程序以及與之相關(guān)的解除程序順序以便在運(yùn)行時(shí)刻將其初始化。
例如,假設(shè)下列部件被編譯TFoo∷Print( )Static int times Called=0cout<<“Hello world”<<timesCalled<<“\n”;timesCalled++;}該編譯程序?qū)⑸蓛刹糠帜繕?biāo)碼并將它們與部件TFoo∷Print相關(guān)。將有用于功能的目標(biāo)碼,以及4字節(jié)的專用數(shù)據(jù)用于靜態(tài)變量timesCalled。
有些看起來就象下文Object code property of TFoo∷Print-code0x0000 LINK A6,#00x0004 MOVE.LA5,--(A7)0x0006 PEA L10x000A MOVE.L<timesCalled>,--(A7)0x000E PEA L20x0012 MOVE.Lcout,--(A7)0x0016 BSR <operator<<(char*)>
0x001C ADDQ.L#8,A70x001E MOVE.LD0,--(A7)0x0020 BSR <operator<<(int)>
0x0026 ADDQ.L#8,A70x0028 MOVE.LD0,--(A7)0x002A BSR <operator(char*)>0x0030 ADDQ.L #8,A70x0032 ADDQ.L #1,<timesCalled>0x0034 UNLK A60x0036 RTSL1DB "\n"L2DB "Hello world"Object code property of TFoo∷Print-data00000000 00000000與目標(biāo)碼一起,編譯程序?qū)⒄f明由于該碼被重新定位而必須采用的不同安排。這些可能看起來象refererce to times CalledOffset 0x0creference to CoutOffset 0x14reference to ostream∷Operator<<(Coust char*)Offset 0x18referenee to Ostream∷Operator<<(int)Offset 0x22refereace to Ostream∷Operator<<(Const Char*)Off-set 0x2creference to times Called Offset 0x34注意安排可以指定對(duì)與同一部件(專用靜態(tài)變量timesCalled)的目標(biāo)的其他部分的引用,或者對(duì)其他部件(例如Cout0的引用。
當(dāng)編輯程序已經(jīng)完全指定了完整的數(shù)據(jù)集和與一個(gè)部件相關(guān)安排時(shí),目標(biāo)碼特性重新對(duì)所有部分定位并在同樣時(shí)刻將其連接起來。在所有部件被編譯后沒有第二個(gè)連接通路。隨著每個(gè)部分新編譯,它也被完全連接。
安排表連接實(shí)質(zhì)上是一個(gè)通過安排表反復(fù)進(jìn)行并以適當(dāng)方式修補(bǔ)代碼的過程。通過一個(gè)分類層級(jí)指定不同類型的安排(fixup),每種安排都知道如何計(jì)算修補(bǔ)值。例如,一個(gè)PC相關(guān)安排知道其必須計(jì)算其定位地址和引用的部件之間的差值。一個(gè)絕對(duì)安排知道必須延遲計(jì)算直到裝入時(shí)刻。雖然連接程序指定了一組安排分類,但新的編譯程序可以指定新型安排。圖20示出了根據(jù)最佳實(shí)施例的一組安排分類。
地址計(jì)算當(dāng)每個(gè)部件被編譯時(shí)進(jìn)行連接的主要問題是其引用的一些部件可能未經(jīng)編譯。
每個(gè)源部件正好是一個(gè)庫(kù)部件的一個(gè)成員。與每個(gè)庫(kù)部件相關(guān)的是一個(gè)裝入模塊特性。該裝入模塊特性清除屬于該共用庫(kù)的所有部件的空間。由于一個(gè)安排準(zhǔn)備計(jì)算一個(gè)修補(bǔ)值,它詢問一個(gè)部件的地址的裝入模塊特性。該裝入模塊特性檢查是否該模塊已為編譯。若是,則返回該部件的地址。若否,則裝入模塊特性根據(jù)該部件的類型執(zhí)行兩個(gè)動(dòng)作。
若該部件的類型是數(shù)據(jù)部件,則返回到恒定地址。若其為一功能部件則為該功能生成一個(gè)連接區(qū),并返回到該連接區(qū)的地址。
目標(biāo)布局如前所述,當(dāng)每個(gè)部件被編譯時(shí),它分配一個(gè)在共享庫(kù)中的位置。隨著其完成,某些多余的工作必須完成以便所有引用是一致的。
若該部件是一數(shù)據(jù)部件,所有它的客戶都被告知它所處的位置。某些客戶可能開始已與假設(shè)地連接,所以這一處理必須清除所有客戶并為其提供正確地址。若該部件為一功能部件,則該功能的連接區(qū)為新地址所更析。應(yīng)當(dāng)注意,這兩種途經(jīng)提供了對(duì)功能的間接存取和對(duì)數(shù)據(jù)的直接存取。
此外,分配有多余空間,以便目標(biāo)碼未來的更新尤其可能使用同樣區(qū)域。多出12%提供給功能而多出25%供給大數(shù)據(jù)目標(biāo)。
連接區(qū)如上所述,當(dāng)為了一個(gè)功能的地址而請(qǐng)求裝入模塊特性的時(shí)候,該特性將給出該連接區(qū)的地址。這意味著每個(gè)功能引用都是間接的,圖21展示了根據(jù)一個(gè)最佳實(shí)施例的連接區(qū)。
應(yīng)當(dāng)注意,不僅內(nèi)部庫(kù)間接通過內(nèi)部連接區(qū)調(diào)用,而且交叉庫(kù)也通過庫(kù)的內(nèi)部連接區(qū)對(duì)功能進(jìn)行間接調(diào)用9即對(duì)庫(kù)B中f2的調(diào)用(2100,2110,2115及2120)這必須完成以便f2可以在無需更新其內(nèi)部和外部客戶的情況下改變位置,并保持一致性從而使功能指針之類的項(xiàng)正確地工作。此外,所有虛擬表功能指針也將指向內(nèi)部連接區(qū)。
任何被引用的但未定義的功能將指向一個(gè)通用“未實(shí)施( )(Unimplemented( ))”功能。由于所有未編譯的功能指向“未實(shí)施( )”。因而程序員不必生成存根模塊功能從而簡(jiǎn)化了裝入和運(yùn)行部分應(yīng)用程序。
具有內(nèi)部連接區(qū)的另一好處是提供了一個(gè)對(duì)所有功能的渠道。在開發(fā)過程中,內(nèi)部連接區(qū)可用于需要功能追蹤的活動(dòng)(例如調(diào)試或性能監(jiān)測(cè))。
增量連接前述討論已對(duì)增量連接的詳細(xì)討論奠定了基礎(chǔ),當(dāng)一個(gè)部件被再編譯時(shí),新部件的尺寸將與舊部件的尺寸進(jìn)行比較以確定是否新部件符合現(xiàn)有定位。若符合,則存在諸位置,并通過它的安排表將語新部件造代,隨即完成聯(lián)接。
若新部件的目標(biāo)碼必須被重新定位,則以前的空間被注以廢棄標(biāo)記,而新目標(biāo)碼被定位到一個(gè)新區(qū)域。然后安排表被迭代。若該部件是一功能,則更新連接入口。連接然后完成。但是,若部件是一數(shù)據(jù)項(xiàng),則該部件必須在客戶表上迭代并更新該部件的引用。然后該數(shù)據(jù)的連接才告完成。
應(yīng)注意起始連接和增量連接按照同樣步驟進(jìn)行。在增量更新中唯一多出的步驟是處理何時(shí)一個(gè)數(shù)據(jù)項(xiàng)必須改變定位。
目標(biāo)碼存儲(chǔ)目標(biāo)碼和裝入模塊特性是通常的部件特性。它們象所有其他特性一樣,存在HOOPS的數(shù)據(jù)庫(kù)中。但是,目標(biāo)碼特性描述目標(biāo)碼但不包含實(shí)際位。實(shí)際位存在由裝入模塊特性所有的段中。該裝入模塊特性有四個(gè)不同的段,它們包括碼、未初始化碼、初始化碼以及連接區(qū)。
圖22展示了根據(jù)最佳實(shí)施例的目標(biāo)碼存儲(chǔ)。每個(gè)圖形目標(biāo)220有一個(gè)關(guān)聯(lián)的裝入模塊特性2250,它包括與圖形目標(biāo)2210,2220,2230和2240相關(guān)聯(lián)的單獨(dú)的目標(biāo)碼。由于所有碼在編譯時(shí)都被連接,并且提供了對(duì)于改變和增量建立的支持,因而裝入模塊特性維護(hù)了位于每個(gè)段中心所有目標(biāo)的映射。它還償試保持用于增長(zhǎng)的多余空間。該多作空間會(huì)浪費(fèi)一些虛擬存儲(chǔ)空間,但并不占用后備存儲(chǔ)器或?qū)嶋H存儲(chǔ)器。若在反復(fù)改變和建立一個(gè)應(yīng)用程序的處理過程中,該多余空間被消耗的情況,則將分配其他空間,受到影響的段必須被重新定位而且所有對(duì)于該段的出入引用必須被更新。
圖23示出了根據(jù)最佳實(shí)施例的裝入庫(kù)。空白區(qū)段2300,2100,2320和2330代表自由空間。該庫(kù)為未初始化數(shù)據(jù)2340,初始化數(shù)據(jù)2350,代碼2360和連接區(qū)2370提供了四個(gè)段。在HOOPS中,這些段沒有空間關(guān)系。連接使用將被裝入的關(guān)系的內(nèi)容而非可能在HOOPS本身內(nèi)具有的關(guān)系。
裝入為了運(yùn)行一個(gè)程序,裝入程序必須有一個(gè)數(shù)據(jù)流式“T裝入模塊”分類。在建立程序過程中,生成一個(gè)數(shù)據(jù)流式“T裝入模塊”,當(dāng)裝入時(shí),把生成的段裝入HOOPS,沒被裝入的應(yīng)用程序和HOOPS共用。這提供了兩個(gè)好處首先,它大大減少了必須復(fù)制的工作量,其次,它使程序在裝入時(shí)進(jìn)行增量更新。
由于裝入程序需要一個(gè)數(shù)據(jù)流式“T裝入模塊”分類,而且“T增量裝入模塊(Tincremental Load Module)要減少流入的信息量,因此,必須寫出從開始到結(jié)束數(shù)據(jù)流。這意味著對(duì)于一個(gè)程序中心大部分改變,“T增量裝入模塊”將不必是再被數(shù)據(jù)流化的。通過使用共享堆陳該“T增量裝入模塊”從HOOPS中得到所有映射信息,否則,任何數(shù)據(jù)定位中心的改變或功能尺寸的改變都需要建立一個(gè)新的“T增量裝入模塊”并被數(shù)據(jù)流化。圖24是一個(gè)根據(jù)一個(gè)最佳實(shí)施例的裝入模塊的存儲(chǔ)映射。
增量更新增量連接簡(jiǎn)化了對(duì)一個(gè)裝入庫(kù)的修改且無需從執(zhí)行中將其去除。這要求在HOOPS中所做的改變?cè)谶\(yùn)行應(yīng)用程序的地址空間中反映出來,這是通過把庫(kù)作為共用段的方式處理的。在HOOPS一例進(jìn)行的任何修改將在運(yùn)行程序側(cè)反映出來。應(yīng)記住,在HOOPS一側(cè),段被解釋為HOOPS數(shù)據(jù)庫(kù)的一部分,而在應(yīng)用程序一側(cè),它只是包含目標(biāo)碼的一個(gè)段。
進(jìn)行程序修改的模式如下調(diào)試程序首先停止執(zhí)行;然后編譯修改后的功能,并把修改后的功能裝入不同位置,雖然它們也符合其現(xiàn)有位置;再對(duì)內(nèi)部連接區(qū)進(jìn)行更新;然后繼續(xù)該程序。若一個(gè)修改的功能在棧上有效,則舊版本將執(zhí)行直到該功能的下一調(diào)用。一個(gè)替代方案是在有效功能被修改時(shí)取消該程序。
出版一個(gè)程序當(dāng)一個(gè)應(yīng)用程序發(fā)行時(shí),連接程序?qū)阉心繕?biāo)碼復(fù)制到數(shù)據(jù)庫(kù)外面的一個(gè)文件中,隨著段被復(fù)制到一個(gè)外部文件,連接程序?qū)λ泄δ苓M(jìn)行再定位及修補(bǔ)。此外,所有內(nèi)部調(diào)用將成為直接調(diào)用,且內(nèi)部連接區(qū)將被去除。除了連接和重新對(duì)目標(biāo)碼定位之外,連接程序必須包括虛擬表生成所需的元數(shù)據(jù)。應(yīng)注意,這一步驟基本是一個(gè)連接而不涉及編譯程序。
還需要第二種出版方式,該方式叫做快速出版。一個(gè)快速出版把需要的段從數(shù)據(jù)庫(kù)復(fù)制到一個(gè)外部文件。第二出版的目的是支持交叉開發(fā)或共享工作的快速換向。
實(shí)施細(xì)節(jié)分類定義<pre listing-type="program-listing"><![CDATA[ enum EObjectKind {kCode,kData, kStaticCtor,kStaticDtor}; class TObjectPropertypublic TProperty{ public TObjectProperty( ); virtual ~TObjectProperty( ); //Compiler Interface virtual void WriteBits(EObjectKind whichOne,LinkSize length, void*theBits,unsigned shortalignment); virtualvoidAdoptFixup(EObjectKindwhichOne,TFixup*theFixup);// Getting/Setting void* CopyBits(EObijectKind whichOne)const; LinkOffset GetOffset(EObjectKindwhichOne)const; LinkSize GetLength(EObjectKind whichOne)const; ELinkSegment GetLinkSegment(EObjectKind whichOne)const; Boolean Contains(EObjectKind whichOne)const; virtual EObjectKind GetPublicKind( )const=0;// Linking virtual void GetLocation(EObjectKindwhichOne,TLocation&fillInLocation)const; TIterator*CreateFixupIterator( )const;}; The object code property delegates the fixup work toindividual fixup objects. class TFixup { public void DoFixup(void*moduleBase)=0; private TComponent*fReference; longfOffset; };]]></pre>
從T Fixup衍生出來的分類為TPcRelative Fixup,Tabso-luteFixup以及TDataRelativeFixup,每一安排分類都清楚如何對(duì)其類型進(jìn)行適當(dāng)?shù)男扪a(bǔ),這與常規(guī)的編譯程序/連接程序交互全然不同,在常規(guī)編程程序/連接程序交互時(shí),連接程序必須對(duì)不同的位進(jìn)行解釋以決定要采取何種行動(dòng)。這一方式另一優(yōu)點(diǎn)在于用于一個(gè)新結(jié)構(gòu)的新編譯程序不必?fù)?dān)心一個(gè)安排類型不為連接程序所支持。
引用類別連接程序必須處理4類引用。它們是碼對(duì)碼,碼對(duì)數(shù)據(jù),數(shù)據(jù)對(duì)碼,以及數(shù)據(jù)對(duì)數(shù)據(jù)。每類引用被處理(對(duì)68K而言)的方式敘述如下碼對(duì)碼例如Foo( );編譯程序根據(jù)文本以兩種不同方式處理這一情況。它可go pc-relative to Foo( ),或可把Foo( )的地址裝入,并直接去往一個(gè)寄存器。任何內(nèi)部調(diào)用都可選用其中一種方式,連接程序?qū)⒖偸菆?bào)告連接區(qū)的地址,交叉庫(kù)調(diào)用必須使用裝入地址的方式,這些將用絕對(duì)地址,這些絕對(duì)地址則在裝入時(shí)刻被修補(bǔ)。
碼對(duì)數(shù)據(jù)例如gValue=1;編譯程序產(chǎn)生一個(gè)對(duì)于gValue的Pc-relative存取,但是,其gValue在一個(gè)不同的共用庫(kù)中時(shí),編譯程序?qū)⒆詣?dòng)生成一個(gè)間接引用。連接程序?qū)⒉东@該間接引用并提供一個(gè)在裝入時(shí)刻由外部地址修補(bǔ)過的本地地址。
數(shù)據(jù)對(duì)碼和數(shù)據(jù)對(duì)數(shù)據(jù)例如(數(shù)據(jù)對(duì)數(shù)據(jù))Void(*pfn)( )=&Foo;例如(數(shù)據(jù)對(duì)數(shù)據(jù))int&pi=i;由于這兩種引用都需要絕對(duì)地址,它們將在裝入時(shí)被處理。在裝入時(shí)刻修補(bǔ)數(shù)據(jù)引用就象修補(bǔ)外部引用一樣。
圖25表示了在每類引用中發(fā)生的情況。若一個(gè)外部庫(kù)要引用同樣的部件,該庫(kù)將在裝入時(shí)刻接收幾個(gè)GetExpor-tadres( )調(diào)用。響應(yīng)于GetExportaddress( )調(diào)用,一個(gè)庫(kù)將返回到功能的內(nèi)部連接區(qū)地址以及數(shù)據(jù)的實(shí)地址。這使得當(dāng)庫(kù)在被裝載時(shí),功能在附近移動(dòng)。
圖26,27,28和29是示明與一最佳實(shí)施例相關(guān)的邏輯的流程圖。圖26展示了控制的“整個(gè)流程,處理起始于2602,該處,建立操作按前述那樣被初始化且處理去往功能框2610以供編譯。這一處理始于功能框2630,在那里,目標(biāo)碼被接受且收集部件的安排,然后,在功能框2640處存儲(chǔ)目標(biāo)碼并在功能框2650處為新改變的目標(biāo)模型進(jìn)行安排,與功能框2640關(guān)聯(lián)的處理詳細(xì)示于圖27中,而與功能框2650的細(xì)節(jié)示于圖28和29中。
圖27是一流程圖,示出了與根據(jù)本發(fā)明的目標(biāo)碼存儲(chǔ)關(guān)聯(lián)的邏輯。處理始于2700并立即去往判別框2710以確定是否這是一個(gè)起始存儲(chǔ)操作。若是,則存儲(chǔ)按功能框2740所示分配,一個(gè)入口在功能框2744中示出的映射中生成或更新,其細(xì)節(jié)示于圖29中,然后該目標(biāo)在功能框2750處存儲(chǔ)。若另一分量在該目標(biāo)被編譯之前已引用了該目標(biāo),則發(fā)生更新。判別框2710將決定是否這是一個(gè)更新操作。然后在判別框2720處進(jìn)行測(cè)試以確定是否該碼與現(xiàn)有位置吻合。若是,則在功能框2750處存儲(chǔ)該目標(biāo),若否,則在功能框2730處消除現(xiàn)有的存儲(chǔ),并在判別框2760處進(jìn)行另一測(cè)試以確定是否該數(shù)據(jù)為目標(biāo)數(shù)據(jù)。若是,則在功能框2762處分配存儲(chǔ),并在功能框2770中在所示的映射中生成入口或更新入口,其細(xì)節(jié)示于圖29中,并且在功能框2750處存儲(chǔ)該目標(biāo)。
圖28展示了安排處理以及與獲取一個(gè)引用目標(biāo)的地址關(guān)聯(lián)的處理的詳細(xì)邏輯。執(zhí)行安排的處理始于2800并馬上去往功能框2810獲取一個(gè)引用目標(biāo)的地址。然后,在判別框2820處,進(jìn)行測(cè)試以確定是否需要絕對(duì)安排。若是,則在功能框2830處為一個(gè)裝入操作注釋該絕對(duì)安排,若否,則用功能框2840所示的相關(guān)位置修補(bǔ)該碼。獲取引用目標(biāo)地址的處理始于功能框2850,在判別框2860處立即進(jìn)行測(cè)試以確定是否一個(gè)目標(biāo)已在映射之中。若是,則地址返回到功能框2880,若否,則在功能框2744所示的映射中行成或更新一個(gè)入口,其細(xì)節(jié)示于圖29,然后地址返回到功能框2880。
圖29是根據(jù)本發(fā)明在一個(gè)映射中生成或更新一個(gè)入口的邏輯。處理始于2900并立即去往判別框2910以確定是否一個(gè)目標(biāo)已在該映射之中,若目標(biāo)存在,則在判別框2930處進(jìn)行測(cè)試以確定目標(biāo)是否為數(shù)據(jù)。若是數(shù)據(jù),則映射為功能框2940所示之新地址所更新。否則,由功能框2920中所示之新地址更新轉(zhuǎn)移位置。若目標(biāo)不在映射中,則在判別框2950處進(jìn)行另一測(cè)試以確定是否該目標(biāo)是數(shù)據(jù),若是,則由功能框2960所示之適當(dāng)?shù)刂飞梢粋€(gè)映射,若否,則由功能框2980所示之連接區(qū)生成一個(gè)對(duì)于以后定義的位置的轉(zhuǎn)移位置,并由連接區(qū)地址將一入口收入該映射中。
雖然本發(fā)明以實(shí)施例方式敘述了本發(fā)明,但本發(fā)明領(lǐng)域的一般技術(shù)人員可了解本發(fā)明的基本原理并可據(jù)其進(jìn)行修改和變型,本發(fā)明的范圍受權(quán)利要求保護(hù)。
權(quán)利要求
1一種連接計(jì)算機(jī)程序的方法,其特征在于包括以下步驟(a)將一個(gè)計(jì)算機(jī)程序模式成一個(gè)部件的集合;(b)在一存儲(chǔ)器中存儲(chǔ)這些部件;(c)訪問所存儲(chǔ)的部件并計(jì)算與每個(gè)部件關(guān)聯(lián)的相關(guān)性以生成一個(gè)相關(guān)性表;(d)根據(jù)該相關(guān)性表編譯部件以生成一個(gè)更新的目標(biāo)模塊;以及(e)通過更新一個(gè)現(xiàn)有的可執(zhí)行文件來連接該更新的目標(biāo)模塊。
2權(quán)利要求1所述的方法,其中,連接該更新的目標(biāo)模塊的步驟與編譯部件的步驟并行發(fā)生。
3權(quán)利要求1所述的方法,其中,只有更新的目標(biāo)模塊被連接。
4權(quán)利要求1所述的方法,包括在存儲(chǔ)器中把目標(biāo)碼作為部件特性存儲(chǔ)的步驟。
5權(quán)利要求1所述的方法,包括存儲(chǔ)一個(gè)包括連接信息的數(shù)據(jù)庫(kù)的步驟。
6權(quán)利要求1所述的方法,包括在連接操作完成時(shí)釋放存儲(chǔ)的步驟。
7權(quán)利要求1所述的方法,還包括以下步驟(a)在存儲(chǔ)器中存儲(chǔ)一個(gè)外部連接區(qū);以及(b)由外部調(diào)用信息在裝入時(shí)刻修補(bǔ)該外部連接區(qū)。
8一種用于連接計(jì)算機(jī)程序的裝置,特征在于包括(a)用于將計(jì)算機(jī)程序成型為一個(gè)部件集合的裝置;(b)用于在存儲(chǔ)器中存儲(chǔ)部件的裝置;(c)用于訪問存儲(chǔ)的部件并計(jì)算與每個(gè)部件關(guān)聯(lián)的相關(guān)性以生成一個(gè)相關(guān)性表的裝置;(d)用于根據(jù)該相關(guān)性表的編譯部件以生成一個(gè)更新的目標(biāo)模塊的裝置;以及(e)用于通過更新一個(gè)現(xiàn)有的可執(zhí)行文件來連接該更新的目標(biāo)模塊的裝置。
9權(quán)利要求8所述裝置,其中所述用于連接更新的目標(biāo)模塊的裝置與用于編譯部件的裝置并行工作。
10權(quán)利要求8所述裝置,其中所述用于連接的裝置只連接更新的目標(biāo)模塊。
11權(quán)利要求8所述裝置,還包括用于把目標(biāo)碼作為部件特性存在存儲(chǔ)器中的裝置。
12權(quán)利要求8所述裝置,還包括用于存儲(chǔ)包括連接信息的數(shù)據(jù)庫(kù)的裝置。
13權(quán)利要求8所述裝置,還包括在連接操作結(jié)束時(shí)釋放存儲(chǔ)的裝置。
14權(quán)利要求8所述的裝置,還包括(a)用于在存儲(chǔ)器中存儲(chǔ)外部連接區(qū)的裝置;以及(b)用于在裝入時(shí)刻由外部調(diào)用信息修補(bǔ)該外部連接區(qū)的裝置。
15一種用于連接計(jì)算機(jī)程序的方法,其特征在于包括(a)將計(jì)算機(jī)程序模式成為一個(gè)部件的一個(gè)集合;(b)在存儲(chǔ)器中存儲(chǔ)部件;(c)訪問所存儲(chǔ)的部件并計(jì)算每個(gè)部件的相關(guān)性以生成一個(gè)相關(guān)性表;(d)根據(jù)該相關(guān)性表編譯部件以生成一個(gè)更新的目標(biāo)模塊;(e)通過更新一個(gè)現(xiàn)有的可執(zhí)行文件來連接更新的目標(biāo)模塊;以及(f)更新一個(gè)裝入的可執(zhí)行文件。
16權(quán)利要求15所述的方法,還包括存儲(chǔ)目標(biāo)模塊以簡(jiǎn)化可執(zhí)行文件的自連接的步驟。
17權(quán)利要求16所述的方法,還包括在存儲(chǔ)目標(biāo)模塊時(shí)進(jìn)行目標(biāo)自連接的步驟。
全文摘要
一個(gè)面向人的目標(biāo)編程系統(tǒng)提供了一個(gè)交互和動(dòng)態(tài)的處理以助于計(jì)算機(jī)程序的增量建立,該增量建立簡(jiǎn)化了諸如操作系統(tǒng)以及有圖形用戶界面的大的應(yīng)用程序之類的復(fù)雜計(jì)算機(jī)程序的開發(fā)。一個(gè)程序被成型為一個(gè)稱為部件的單元集。一個(gè)部件表示一個(gè)象分類或功能性之類的可編譯語言成分。三個(gè)主要的功能性是數(shù)據(jù)庫(kù),編譯程序和建立處理。一個(gè)增量連接程序在建立處理中操作以生成由裝入程序所用的文件。
文檔編號(hào)G06F9/445GK1102934SQ94190010
公開日1995年5月24日 申請(qǐng)日期1994年1月6日 優(yōu)先權(quán)日1993年6月28日
發(fā)明者羅杰·P·勞倫斯, 約翰·R·丹斯 申請(qǐng)人:塔里根特公司