Electrical Network Interactive Analysis Console
and the Eniac Extension language
SourceForge.net Logo

The Eniac language and the Eniac VM

Eniac is basically a mathematical program, commands must respect a particular language.
So, you can use ENIAC like a scientific calculator, it's possible to do complex numbers, polynomial, or matrix calculation in a simple way.

Initially I had not planned to use flow control statements (like "for", "if","while"),
but then I realized that they could be very useful (for example, if I want to analyse an electrical network varying a parameter inside a range...).
So, now Eniac has a real programming language with all the constructs available in other languages.
It's possible define variables (typed) and data structures; define functions with local variables and possibility to access to global variables.


This page are divised in the following paragraphs: Return to main page

How the Eniac language is translated in EniacVM code and interpreted

Below shows the debug execution of a simple function which calculate the surface area of a circle.
You can see how the eniac script is translated in EniacVM code.

ENIAC Electrical Networks Interactive Analysis Console (v1R8 14/02/09)

(Enter help to show info.)

Write "menu" to show Eniac demo menu

ENIAC> function circle_area(radius)
ENIAC.> area=pi*radius^2
ENIAC.> return area
ENIAC.> end

ENIAC> circle_area(10)
 314.159

ENIAC> debug 2

ENIAC> circle_area(10)

000 circle_area(10)
001     R7=[]                # A=
002     PUSH  10->R7         # A=
003     A=R7                 # A=[ 10]
004     A=circle_area(A)
 000 function circle_area(radius)
 001     radius=A[0]          # A=[ 10]
 002 area=pi*radius^2
 003     A=pi                 # A= 3.14159
 004     R9=A                 # A= 3.14159
 005     A=radius             # A= 10
 006     R10=A                # A= 10
 007     A=R10^ 2             # A= 100
 008     A=R9*A               # A= 314.159
 009     area=A               # A= 314.159
 010 return area
 011     A=area               # A= 314.159
 012     END
 # A= 314.159
 314.159

ENIAC> debug 0

Go up to page index  Return to main page

Mathematical and functions operations

You can get all defined variables writing 'globals' on the console.
There are a lot of library functions (and more will be added), you can get a minimal help on them, writing 'help' on the console.

See the output produced by the file "example.txt" (which you can found into download package):


# 
Reading from example.txt

#
#-----------------------------------------------------------
# basic math operations
#-----------------------------------------------------------
#
ENIAC> a=1/2*4+(5*sqrt(8^3))
 115.137
ENIAC> ans   # ans report last operation result
 115.137
ENIAC> b=(a+1)/2
 58.0685
ENIAC> c=1+5*j   # j is the imaginary unit
 1+5*j
ENIAC> d=c/j
 5-j
ENIAC> e=sin(2*pi*d)
-3.27895e-013-267.745*j
ENIAC> f=true
true
ENIAC> g=1/inf
 0
#
#-----------------------------------------------------------
# list operations
#-----------------------------------------------------------
#
ENIAC> l=[1,2,3,4]
[ 1, 2, 3, 4]
ENIAC> v1=l[0]      # return 1
 1
ENIAC> l[2]=[7,8]   # set l=[1,2,[7,8],4]
[ 7, 8]
ENIAC> v2=l[2,1]    # return 8
 8
ENIAC> push("l",5)  # set l=[1,2,[7,8],4,5]
 5
ENIAC> k=pop("l")   # return 5 and set l=[1,2,[7,8],4]
 5
ENIAC> assign v1,v2,v3 = l   # multiple variable assignment 

ENIAC> len l        # return number of items 

#
#-----------------------------------------------------------
# map operations
#-----------------------------------------------------------
#
ENIAC> m={first:11, second:22, third:{x:640,y:480} }
{
 first<number>  :  11,
 second<number> :  22,
 third<map>     : {
   x<number> :  640,
   y<number> :  480
  }
}
ENIAC> m.first
 11
ENIAC> m.second
 22
ENIAC> m.third.x
 640
ENIAC> m.third.y
 480
ENIAC> m.forth=4
 4
ENIAC> m
{
 first<number>  :  11,
 forth<number>  :  4,
 second<number> :  22,
 third<map>     : {
   x<number> :  640,
   y<number> :  480
  }
}
ENIAC> m["first"]
 11
ENIAC> m.third["x"]=800
 800
ENIAC> merge("m",{a:"a",b:"b"})
{
 a<string>      : "a",
 b<string>      : "b",
 first<number>  :  11,
 forth<number>  :  4,
 second<number> :  22,
 third<map>     : {
   x<number> :  800,
   y<number> :  480
  }
}
ENIAC> remove "m.forth"   # remove field

ENIAC> map=m
{
 a<string>      : "a",
 b<string>      : "b",
 first<number>  :  11,
 second<number> :  22,
 third<map>     : {
   x<number> :  800,
   y<number> :  480
  }
}
ENIAC> remove "m"         # remove variable  

ENIAC> m
Variable or function 'm' not found.
#
#-----------------------------------------------------------
# polynomial operations
#-----------------------------------------------------------
#
ENIAC> p=(s-1)*(s-2)*(s-3)*(s-4)*(s-5)
s^5-15*s^4+85*s^3-225*s^2+274*s-120
ENIAC> solve(p)
[ 3, 2, 4, 1, 5]
ENIAC> q=diff(p)       # differentiation
5*s^4-60*s^3+255*s^2-450*s+274
ENIAC> r=integrate(q)  # integration
s^5-15*s^4+85*s^3-225*s^2+274*s
#
#-----------------------------------------------------------
# fract operations
#-----------------------------------------------------------
#
ENIAC> f=p/(p-1)^2
     1                                         -0.00833333*s^5+0.125*s^4-0.708333*s^3+1.875*s^2-2.28333*s+1                                  
- ------- * ---------------------------------------------------------------------------------------------------------------------------------
  122.008   6.83013e-005*s^10-0.00204904*s^9+0.026979*s^8-0.204904*s^7+0.99194*s^6-3.19049*s^5+6.88717*s^4-9.82651*s^3+8.8468*s^2-4.52893*s+1
ENIAC> f=f*(s+2)/(s-2)
    1                                       -0.00416667*s^6+0.0541667*s^5-0.229167*s^4+0.229167*s^3+0.733333*s^2-1.78333*s+1                                 
 ------- * --------------------------------------------------------------------------------------------------------------------------------------------------
 122.008   -3.41507e-005*s^11+0.00109282*s^10-0.0155386*s^9+0.129431*s^8-0.700874*s^7+2.58719*s^6-6.63408*s^5+11.8004*s^4-14.2499*s^3+11.1113*s^2-5.02893*s+1
ENIAC> zeros=solve(num(f))
[ 3, 2, 4, 1, 5,-2]
ENIAC> polos=solve(den(f))
[ 1.04592+1.75992e-007*j, 1.04592-1.75992e-007*j, 3.27585, 3.27581, 3.79071, 2, 1.84902+2.52157e-006*j, 1.84902-2.52157e-006*j, 5.0385, 5.03849, 3.79076]
#
#-----------------------------------------------------------
# matrix operations
#-----------------------------------------------------------
#
ENIAC> A=matrix([[1,2,3],[4,5,6],[7,8,3]])

   0 1 2 
---------
0: 1 2 3 
1: 4 5 6 
2: 7 8 3 

ENIAC> det(A)
18
ENIAC> I=ident(4)

   0 1 2 3 
-----------
0: 1 0 0 0 
1: 0 1 0 0 
2: 0 0 1 0 
3: 0 0 0 1 

ENIAC> M=diag([1,2*s,3*s+1,4,5*s^2])

   0   1     2 3     4 
-----------------------
0: 1   0     0 0     0 
1: 0 2*s     0 0     0 
2: 0   0 3*s+1 0     0 
3: 0   0     0 4     0 
4: 0   0     0 0 5*s^2 

ENIAC> l=det(M)        # determinant 
120*s^4+40*s^3

ENIAC> B=matrix([1,2,3])

   0
-----
0: 1
1: 2
2: 3

ENIAC> transpose(B)

   0 1 2
---------
0: 1 2 3

ENIAC> B*transpose(B)

   0 1 2
---------
0: 1 2 3
1: 2 4 6
2: 3 6 9

ENIAC> transpose(B)*B

    0
------
0: 14

ENIAC> D=B*4*transpose(B)
    0  1  2
------------
0:  4  8 12
1:  8 16 24
2: 12 24 36

ENIAC> E=A+D

    0  1  2
------------
0:  5 10 15
1: 12 21 30
2: 19 32 39

#
# Calculation of Characteristic polynomial
#

ENIAC> char_poly=det(D-s*ident(3))
-s^3+56*s^2

#
# eigenvalues calculation
#

ENIAC> eigenvalues=solve(char_poly)
[ 0, 0, 56]

#
#-----------------------------------------------------------
# print all variables
#-----------------------------------------------------------
#
ENIAC> globals
A<matrix>       = matrix([[1,2,3],[4,5,6],[7,8,3]])
B<matrix>       = matrix([[1],[2],[3]])
D<matrix>       = matrix([[4,8,12],[8,16,24],[12,24,36]])
E<matrix>       = matrix([[5,10,15],[12,21,30],[19,32,39]])
I<matrix>       = matrix([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]])
M<matrix>       = matrix([[1,0,0,0,0],[0,2*s,0,0,0],[0,0,3*s+1,0,0],[0,0,0,4,0],[0,0,0,0,5*s^2]])
Y<matrix>       = matrix([[0]])
a<number>       =  115.137
ans<polynomial> = 120*s^4+40*s^3
b<number>       =  58.0685
c<number>       =  1+5*j
d<number>       =  5-j
e<number>       = -3.27895e-013-267.745*j
f<fract>        = (s^6-13*s^5+55*s^4-55*s^3-176*s^2+428*s-240)/(s^11-32*s^10+455*s^9-3790*s^8+20523*s^7-75758*s^6+194259*s^5-345540*s^4+417266*s^3-325360*s^2+147257*s-29282)
g<number>       =  0
k<number>       =  5
l<polynomial>   = 120*s^4+40*s^3
lasterr<error>  = Variable or function 'm' not found.
map<map>        = {a<string>:"a", b<string>:"b", first<number>: 11, second<number>: 22, third<map>:{x<number>: 800, y<number>: 480}}
netmat<string>  = "Y"
p<polynomial>   = s^5-15*s^4+85*s^3-225*s^2+274*s-120
pi<number>      =  3.14159
polos<list>     = [ 1.04592+1.75992e-007*j, 1.04592-1.75992e-007*j, 3.27585, 3.27581, 3.79071, 2, 1.84902+2.52157e-006*j, 1.84902-2.52157e-006*j, 5.0385, 5.03849, 3.79076]
q<polynomial>   = 5*s^4-60*s^3+255*s^2-450*s+274
r<polynomial>   = s^5-15*s^4+85*s^3-225*s^2+274*s
v1<number>      =  1
v2<number>      =  8
zeros<list>     = [ 3, 2, 4, 1, 5,-2]

#
#-----------------------------------------------------------
# electrical operations
#
# A simple passband filter
#-----------------------------------------------------------
#

#clear netmat structure
ENIAC> @netmat={}

ENIAC> C( [1,2] , 0.1p  )
insert C[ 1, 2]=1e-013 into Y
ENIAC> R( [2,0] , 1K    )
insert R[ 2, 0]=1000 into Y
ENIAC> R( [2,3] , 100K  )
insert R[ 2, 3]=100000 into Y
ENIAC> C( [3,0] , 10u   )
insert C[ 3, 0]=1e-005 into Y
ENIAC>  @netmat.Y   #show admittance matrix

                0         1                2               3 
-------------------------------------------------------------
0: 1e-005*s+0.001         0           -0.001       -1e-005*s 
1:              0  1e-013*s        -1e-013*s               0 
2:         -0.001 -1e-013*s 1e-013*s+0.00101         -1e-005 
3:      -1e-005*s         0          -1e-005 1e-005*s+1e-005 

ENIAC> f=Gain([3],[1])
    s              1         
 ------ * -------------------
 1e+010   1e-010*s^2+1.01*s+1
ENIAC> bode(f)

Frequency range = [0.00157579,1.60746e+011] Hz
Amplitude range = [-240.173,-200.087] dB
zero = 0 Hz
pole = 0.157579 Hz
pole = 1.60746e+009 Hz
Bode diagrams plotted to "image.gif" (800x400)


Go up to page index  Return to main page

Flow control constructs

The following are the main constructs supported by Eniac.
There is still no support for objects and object-oriented programming, but I'm working on that!!


#===========================================
# if then else
#===========================================

a=1
b=2

if a==1 and not (b==3) 
  println "condition is true"
else
  println "condition is false"
end
 
#===========================================
# for loop
#===========================================

  for i=0;i<10;i=i+1
    if i==4 continue end
    print i
    if i>7
      println " premature end of for"
      break
    end
  end

#===========================================
# while loop
#===========================================
  
  i=0
  while i<10
    i=i+1
    if i==4 continue end
    print i
    if i>7
      println " premature end of while"
      break
    end   
  end

#===========================================
# do loop
#=========================================== 
  
  i=0
  do
    i=i+1   
    if i==4 continue end
    print i
    if i>7
      println " premature end of do-until"
      break
    end
  until i<10

#===========================================
# switch
#===========================================

i=100
k=20

switch i
  case 100:
    print "100"
    switch k
      case 10: print "-10" break
      case 20: print "-20" break
      default: print "-def" break
    end
    println
    break

  case 200: println "200" break
  case 400: println "400" break	
  default:  println "def" break	

end

#=================================
# function calls
#=================================

function test(updateGlobal)
  println "TEST: a=" + a + " (this is global because local don't exist yet)"
  a=456
  println "TEST: a=" + a + " (this is a local)"
  println "TEST: a=" + global.a + " (this is the way to access global)"
  if updateGlobal
    global.a=global.a+1
    println "TEST: a="+a+" global.a="+global.a
  end
end

a=123

println "MAIN: a=" + a
test(false)
updateGlobal=1
test(true)
println "MAIN: a=" + a + " updated by test"


Go up to page index  Return to main page

Eniac Semantic Algebra

Below is shown the semantic algebra used by Eniac.

 program:
   expr
   program;program
   if condition_or code_block
   if condition_or code_block else code_block
   for lvalue;condition_or;expr code_block 
   while condtion_or code_block
   do code_block until condition_or
   do code_block       # single code block are enclosed by do..end
   switch expr codeblock
   break
   continue
   case expr: program
   default: program
   function name(varList) codeblock
   return expr
   assign varlist

 code_block:
   program end
   program else
   program until

 varlist:
   name         
   name,varlist 
   varlist=expr  --assign list to multiple var  i.e.: x,y,x=[1,2,3]  

 list-expr: 
   expr
   expr;list-expr

 expr:
   expr+term
   expr-term
   term

 term:
   term/factor
   term*factor
   factor

 factor:
   operand^operand
   operand

 operand:
   number
   -factor     
   (expr)
   unkvar       # for create polynomial 
   imagunit     # for create complex number
   lvalue       # store operations
   @lvalue      # indirect store operations
   [expr]       # list definition like [1,2,3,6+7,s^5]
   {datamap}    # hash map definition	like {first:33, second:77}

 lvalue:
   name         # recall var or call function without arguments	
   name.lvalue  # define structure
   lvalue=expr  # assign to var
   lvalue(list) # function call
   lvalue[list] # access list item 

 list:
   expr
   empty	       # permits empty items [1,2,,4] 		
   expr,list

 datamap:
   empty        # permits {}
   name: expr
   name: expr,datamap

 condition_or:
   condition_or or condition_and
   condition_and

 condition_and:
   condition_and and condition_factor
   condition_factor

 condition_factor:
   not condition_factor
   (condition_or)
   condition

 condition:
   expr <  expr
   expr <= expr
   expr == expr
   expr != expr
   expr >= expr
   expr >  expr
        


Go up to page index  Return to main page