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