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 中的 ? : 运算符)。这些是关于编译器的所有我能想到的错误。