跳转到内容

Aros/开发者/文档/E

来自 Wikibooks,开放世界中的开放书籍
用于 Aros 维基教科书的导航栏
Aros 用户
Aros 用户文档
Aros 用户常见问题解答
Aros 用户应用程序
Aros 用户 DOS Shell
Aros/用户/AmigaLegacy
Aros 开发文档
Aros 开发者文档
从 AmigaOS/SDL 移植软件
Zune 初学者
Zune .MUI 类
SDL 初学者
Aros 开发者构建系统
特定平台
Aros x86 完整系统 HCL
Aros x86 音频/视频支持
Aros x86 网络支持
Aros Intel AMD x86 安装
Aros 存储支持 IDE SATA 等
Aros Poseidon USB 支持
x86-64 支持
摩托罗拉 68k Amiga 支持
Linux 和 FreeBSD 支持
Windows Mingw 和 MacOSX 支持
Android 支持
Arm Raspberry Pi 支持
PPC Power Architecture
杂项
Aros 公共许可证

阅读更多 这里.

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

华夏公益教科书