Aros/開發者/文件/E
閱讀更多 這裡.
Amiga E,或更常稱為E,是 Wouter van Oortmerssen 在 Amiga 上建立的一種程式語言。
Amiga E 結合了許多語言的特性,但在基本概念方面最接近原始的 C 程式設計 和 C++,因為它速度快且型別弱,並且具有來自過程式、面向物件和函數語言程式設計語言的豐富功能集。
Amiga E 的主要優勢是編譯速度快(允許它用作指令碼語言的替代品)、原始碼可讀性強、靈活的型別系統、強大的模組系統、異常處理(不是 C++ 變體)和麵向物件程式設計。
聯絡 AmigaE IRC 頻道 irc.freenode.net 上的 #amigaE
有關更多資訊和問題,PortablE 有自己的論壇 這裡。 PortablE 是一個用 E 從頭編寫的 AmigaE 編譯器,可以自己編譯。有一個 郵件列表 用於 E,您可能在那裡找到一些答案。
閱讀更多 這裡.
這就是 PortablE 的工作原理。您編寫 Amiga E 程式碼,使用 PortablE 將其轉換為 .cpp 檔案,然後使用任何 C++ 編譯器將該檔案編譯成可執行檔案。我一直在 AROS 中使用 g++。如果您想轉到 Amiga Classic,您可以使用 PortablE 轉換為 Amiga E,然後將其移動到 Classic,在那裡您可以使用像 CreativE 這樣的 Amiga E 編譯器。
如果 PortablE 尚未設定好,您需要設定至少 100000 的堆疊才能執行 PortablE。您可以在 AROS shell 中設定它。
stack 100000
您需要為 PEmodules 設定一個賦值。
Assign PEmodules: VolumeName:PEmodules
您可以在 AROS 的使用者啟動檔案中放置像這樣的賦值命令,這樣您就不必每次都執行它。使用者啟動檔案位於 System:S(S 抽屜)中。
您還需要在其中放置一些針對 g++ 的賦值。您需要的確切賦值可以在 System:Development 中的 INSTALL 檔案中找到。
因此,以下是我在設定好一切後在命令列中輸入的命令,以測試一個簡單的程式。
PortablE test.e (This gave me a file named test.cpp)
g++ test.cpp -o test (This gave me a file named test to run as an executable)
然後,我只需要在 shell 中輸入可執行檔案的名稱,它就會執行並列印“Hello, World!”。
閱讀更多 這裡.
在 Amiga E 中使用另一個過程的 "hello world" 程式
PROC main()
DEF z
WriteF('Hello, World!\n')
z:=1
Another()
ENDPROC
PROC another
DEF y
y:=2
ENDPROC
IF x>0
x:=x+1
WriteF('Increment: x is now \d\n', x)
ELSEIF x<0
x:=x-1
WriteF('Decrement: x is now \d\n', x)
ELSE
WriteF('Zero: x is 0\n')
ENDIF
SELECT x
CASE 0
WriteF('x is zero\n')
CASE 10
WriteF('x is ten\n')
CASE -2
WriteF('x is -2\n')
DEFAULT
WriteF('x is not zero, ten or -2\n')
ENDSELECT
PROC main()
DEF x
x:=1
WHILE x<=100
WriteF('\d ', x)
x:=x+1
ENDWHILE
WriteF('\n')
ENDPROC
PROC main()
DEF x
x:=1
REPEAT
WriteF('\d ', x)
x:=x+1
UNTIL x>100
WriteF('\n')
ENDPROC
PROC main()
DEF x,y
x:=1
y:=2
WHILE (x<10) AND (y<10)
WriteF('x is \d and y is \d\n', x, y)
x:=x+2
y:=y+2
ENDWHILE
ENDPROC
- 過程定義。
- 宣告過程 main,沒有引數。
- 宣告區域性變數 x 和 y
- 使用賦值語句初始化 x 和 y。
- WHILE 迴圈
- 使用邏輯運算子 AND、比較運算子 < 和圓括號對錶達式進行分組的 WHILE 迴圈檢查。
- 使用引數呼叫(內建)過程 WriteF。請注意字串、數字佔位符 \d 和換行符 \n。
- 對 x 和 y 進行賦值,將其值加 2。
- WHILE 迴圈結束的標記。
- 過程結束的標記。
要返回值,請將 ENDPROC 替換為 ENDPROC value
閱讀更多關於 這裡.
常量
數字
字串
命名
列舉
集合
LONG
PTR
ARRAY
OBJECT
LIST
STRING
連結串列
- 常量 - TRUE、FALSE、NIL、ALL、GADGETSIZE、OLDFILE、NEWFILE、STRLEN
- 變數 - arg、wbmessage、stdout、conout、stdrast、dosbase、execbase、gfxbase、intuitionbase,
- 函式 - \c(數字字元) - \d(數字十進位制) - \h(數字十六進位制)、\s(字串字串)
- 函式 - \l 在欄位中左對齊、\r 在欄位中右對齊、\z 將填充字元設定為“0”
- 函式 - WriteF、StringF、Out、Inp、ReadStr、FileLength、SetStdOut,
- 函式(直覺) - OpenW、CloseW、OpenS、CloseS、Gadget、Mouse、MouseX、MouseY、WaitIMessage,
- 函式(圖形) - Plot、Line、Box、Colour、TextF、SetStdRast、SetTopaz,
- 函式(數學) - Abs、Even、Odd、Mod、Rnd、RndQ、Shl、Shr、Long、Int、Char、PutLong、PutInt、PutChar,
- 函式(系統) - New、Dispose、DisposeLink、CleanUp、CtrlC、FreeStack,
從 BASIC 轉移到 C、C++ 和 E 時最困難的部分是指標和字串。E 和 C 處理字串的方式幾乎完全相同,因此 E 在這裡沒有太大的優勢。
由於 C 的設計,AmigaE 對指標的處理比 C 的處理簡單得多。您必須非常仔細地考慮需要哪種型別的指標,以防需要新增“&”或“*”。而在 E 中,幾乎永遠不會有這種擔憂。
此外,“PTR TO xxx”似乎比“xxx*”更容易理解。
請注意,有一些很好的 C 指南解釋了字串和指標的原理,使用“方框和箭頭”圖,這些指南在學習 E 時可能仍然對您有所幫助。
您可以直接開啟 workbench.library(需要版本 44 或更高版本)並呼叫 OpenWorkbenchObjectA(),如 autodocs 中所述。
/* DirList3.e */
MODULE 'std/cGUI', 'std/cPath'
STATIC app_name = 'DirList'
PROC main()
DEF dirPath:STRING, dir:PTR TO cDir, dirList:PTR TO cDirEntryList
DEF win:PTR TO cGuiWindow, guiLastFile:PTR TO cGuiTextBox, guiOK
DEF quit:BOOL, item:PTR TO cGuiItem, entry:PTR TO cGuiFixedListEntry
->describe our app
CreateApp(app_name).initDescription('This is a simple PortablE demo.').build()
->scan directory
dirPath := ImportDirPath('EnvArc:')
NEW dir.new()
IF dir.open(dirPath, /*readOnly*/ TRUE) = FALSE THEN Throw("ERR", 'Failed to open directory')
dirList := dir.makeEntryList()
dir.close()
->build the GUI
win := CreateGuiWindow(app_name)
win.beginGroupVertical()
win.addTextBox('').setState('Below is a list of all the files inside EnvArc:')
win.beginFixedList().initSelectableEntries(/*multiSelect*/ TRUE)
->step through each file
IF dirList.gotoFirst(/*any0file1dir2*/ 1)
REPEAT
->add line for file
win.addFixedListEntry(dirList.infoName())
UNTIL dirList.gotoNext(1) = FALSE
ENDIF
win.endFixedList()
guiLastFile := win.addTextBox('The last ticked file:')
guiOK := win.addButton('OK')
win.endGroup()
win.build()
->handle user interaction with GUI
quit := FALSE
REPEAT
item := WaitForChangedGuiItem()
IF item = NIL
IF win.getCloseRequest() THEN quit := TRUE
ELSE IF item = guiOK
quit := TRUE
ELSE IF item.IsOfClassType(TYPEOF cGuiFixedListEntry)
entry := item::cGuiFixedListEntry
IF entry.getState()
->(a file was ticked) so tell user which file they just ticked
guiLastFile.setState(entry.infoLabel())
ENDIF
ENDIF
UNTIL quit
win.close()
FINALLY
PrintException()
END dirPath, dir
ENDPROC
-> Shared MUI Custom Class Skeleton. Needs minimum ECX 2.x
OPT PREPROCESS
#define CLASS_NAME 'mytest.mcc'
#define CLASS_VERSION 1
#define CLASS_REVISION 0
#define CLASS_IDSTRING 'mytest.mcc by me'
->#define ONLYGLOBAL
->#define INFOCLASS
#ifdef __MORPHOS__
OPT EXENAME = CLASS_NAME + '.elf'
#else
OPT EXENAME = CLASS_NAME
#endif
#define SUPERCLASS MUIC_Area
->#define SUPERCLASSP
-> Let ECX create a convenient multi base library for us
LIBRARY CLASS_NAME, CLASS_VERSION, CLASS_REVISION, CLASS_IDSTRING IS
mcc_query(D0)
#define DoMethodA(obj,attrs) doMethodA(obj,attrs)
#define DoSuperMethodA(class,obj,attrs) doSuperMethodA(class,obj,attrs)
#define CoerceMethodA(class,obj,attrs) coerceMethodA(class,obj,attrs)
-> handy..
#ifdef DEBUG
#define DEBUGF(str,...) DebugF(str,...)
#else
#define DEBUGF(str,...)
#endif
MODULE 'amigalib/boopsi'
MODULE 'muimaster',
'libraries/mui',
'libraries/muip',
'mui/muicustomclass'
MODULE 'intuition/intuition',
'intuition/classes',
'intuition/classusr'
MODULE 'exec/libraries',
'exec/nodes',
'exec/memory'
MODULE 'utility',
'utility/tagitem',
'utility/hooks'
OBJECT classdata
ENDOBJECT
OBJECT classdatap
ENDOBJECT
STATIC g_usedclasses=[NIL]
STATIC g_usedclassesp=[NIL]
STATIC g_shorthelp = ''
DEF g_prefsimageobject=NIL
DEF g_thisclass=NIL:PTR TO mui_customclass
DEF g_thisclassp=NIL:PTR TO mui_customclass
PROC main() HANDLE
IFN muimasterbase := OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN) THEN
Throw("LIB", MUIMASTER_NAME)
IFN utilitybase := OpenLibrary('utility.library',39) THEN
Throw("LIB", 'utility.library')
#ifdef SUPERCLASS
IFN g_thisclass := eMui_CreateCustomClass(librarybase,SUPERCLASS,NIL,
SIZEOF classdata,{classDispatcher})
Raise("CMCC")
ENDIF
#endif
#ifdef SUPERCLASSP
IFN g_thisclassp := eMui_CreateCustomClass(librarybase,SUPERCLASSP,NIL,
SIZEOF classdatap,{classDispatcherP})
Raise("CMCC")
ENDIF
#endif
EXCEPT
DebugF('mcc open() failed: ')
SELECT exception
CASE "LIB" ; DebugF('Could not open library "\s"\n', exceptioninfo)
CASE "CMCC" ; DebugF('Could not create mui custom class\n')
DEFAULT ; DebugF('Unknown exception $\h\n', exception)
ENDSELECT
close()
RETURN NIL -> make OpenLibrary() fail.
ENDPROC TRUE
PROC close()
IF g_thisclassp THEN Mui_DeleteCustomClass(g_thisclassp)
IF g_thisclass THEN Mui_DeleteCustomClass(g_thisclass)
CloseLibrary(utilitybase)
CloseLibrary(muimasterbase)
ENDPROC
-> the special fuction needed for any MCC
PROC mcc_query(which)
SELECT which
CASE 0
RETURN g_thisclass
CASE 1
RETURN g_thisclassp
CASE 2
RETURN g_prefsimageobject
CASE 3
#ifdef ONLYGLOBAL
RETURN TRUE
#else
RETURN FALSE
#endif
CASE 4
#ifdef INFOCLASS
RETURN TRUE
#else
RETURN FALSE
#endif
CASE 5
RETURN g_usedclasses
CASE 6
RETURN g_usedclassesp
CASE 7
RETURN g_shorthelp
ENDSELECT
ENDPROC NIL
#ifdef SUPERCLASS
PROC classDispatcher(cl:PTR TO iclass, obj:PTR TO object, msg:PTR TO opset)
SELECT msg.methodid
-> CASE OM_NEW ; RETURN classNew (cl,obj,msg)
-> CASE OM_DISPOSE ; RETURN classDispose (cl,obj,msg)
-> CASE MUIM_AskMinMax ; RETURN classAskMinMax(cl,obj,msg)
-> CASE MUIM_Show ; RETURN classShow(cl, obj, msg)
-> CASE MUIM_Hide ; RETURN classHide(cl, obj, msg)
-> CASE OM_SET ; RETURN classSet(cl,obj,msg)
-> CASE OM_GET ; RETURN classGet(cl,obj,msg)
ENDSELECT
ENDPROC DoSuperMethodA(cl,obj,msg)
#endif
#ifdef SUPERCLASSP
PROC classDispatcherP(cl:PTR TO iclass, obj:PTR TO object, msg:PTR TO opset)
ENDPROC
#endif
PROC classNew(cl:PTR TO iclass,obj:PTR TO object,msg:PTR TO opset)
DEF data:PTR TO classdata
IFN obj := DoSuperMethodA(cl,obj,msg) THEN RETURN 0
data := INST_DATA(cl,obj)
ENDPROC obj
PROC classDispose(cl:PTR TO iclass,obj:PTR TO object,msg:PTR TO msg)
DEF data:PTR TO classdata
data := INST_DATA(cl,obj)
ENDPROC DoSuperMethodA(cl,obj,msg)
PROC classSet(cl:PTR TO iclass,obj:PTR TO object,msg:PTR TO opset)
DEF data:REG PTR TO classdata, tags:PTR TO tagitem, tag:REG PTR TO tagitem
data := INST_DATA(cl,obj)
tags := msg.attrlist
WHILE tag := NextTagItem({tags})
SELECT tag.tag
->CASE MUIA_Xxx_Yyy
->data.xxxyyy := tag.data
DEFAULT
ENDSELECT
ENDWHILE
ENDPROC DoSuperMethodA(cl,obj,msg)
PROC classGet(cl:PTR TO iclass,obj:PTR TO object,msg:PTR TO opget)
DEF data:PTR TO classdata
data := INST_DATA(cl,obj)
SELECT msg.attrid
->CASE MUIA_Xxx_Yzz
-> PutLong(msg.storage,data.xxxyyy)
-> RETURN MUI_TRUE
ENDSELECT
ENDPROC DoSuperMethodA(cl,obj,msg)
PROC classAskMinMax(cl:PTR TO iclass,obj:PTR TO object,msg:PTR TO muip_askminmax)
DEF data:PTR TO classdata, mi:PTR TO mui_minmax
DoSuperMethodA(cl,obj,msg)
data := INST_DATA(cl,obj)
mi := msg.minmaxinfo
mi.minwidth += 16
mi.minheight += 16
mi.defwidth += 128
mi.defheight += 128
mi.maxwidth += MUI_MAXMAX
mi.maxheight += MUI_MAXMAX
ENDPROC 0
PROC classShow(cl:PTR TO iclass, obj:PTR TO object, msg:PTR TO opset)
DEF data:PTR TO classdata
IFN DoSuperMethodA(cl,obj,msg) THEN RETURN FALSE
data := INST_DATA(cl, obj)
ENDPROC MUI_TRUE
PROC classHide(cl:PTR TO iclass, obj:PTR TO object, msg:PTR TO opset)
DEF data:PTR TO classdata
data := INST_DATA(cl, obj)
ENDPROC DoSuperMethodA(cl, obj, msg)
AmigaE 執行良好,也與彙編整合良好。只是不要用它編寫共享庫,因為庫模式存在設計缺陷。另外,如果您計劃使用多個返回值,請將它們保留在您的應用程式程式碼的相同原始碼中,因為模組生成在使用多個返回值時無法正常工作。最後,不要巢狀 IF 關鍵字的函式形式(AmigaE 中相當於 C 中的 ? : 運算子)。這些是關於編譯器的所有我能想到的錯誤。